제한된 샌드박스 만들기
안전한 _ENV 허용 목록을 만들고 load()로 신뢰할 수 없는 코드를 실행합니다.
제한된 샌드박스 만들기은(는) CoddyKit의 무료 Lua Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Lua Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Lua Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
목표
제한된 샌드박스를 사용하면 신뢰할 수 없는 Lua 코드를 안전하게 실행할 수 있습니다. 코드는 계산을 수행하고 문자열과 수학 기능을 사용할 수 있지만 파일 시스템, OS 또는 네트워크에는 접근할 수 없습니다.
허용 목록 방식
안전하고 동작을 명확히 이해할 수 있는 함수만 포함하여 샌드박스 환경을 처음부터 구성합니다.
local function makeSandbox()
return {
print = print,
type = type,
tostring = tostring,
tonumber = tonumber,
pairs = pairs,
ipairs = ipairs,
next = next,
select = select,
unpack = table.unpack,
error = error,
pcall = pcall,
xpcall = xpcall,
math = math,
string = { format=string.format, find=string.find,
match=string.match, gmatch=string.gmatch,
gsub=string.gsub, sub=string.sub,
len=string.len, byte=string.byte, char=string.char },
table = { insert=table.insert, remove=table.remove,
concat=table.concat, sort=table.sort,
unpack=table.unpack, move=table.move },
}
end샌드박스에서 코드 실행
샌드박스를 _ENV로 지정하여 사용자 코드를 불러오고 실행합니다.
local function runSandboxed(code, env)
local fn, err = load(code, "user", "t", env)
if not fn then return nil, err end
return pcall(fn)
end
local env = makeSandbox()
local ok, err = runSandboxed("return 1+1", env)
print(ok, err) -- true 2출력 캡처
print를 표준 출력에 쓰는 대신 버퍼에 추가하는 사용자 지정 함수로 바꿉니다.
local output = {}
env.print = function(...)
local parts = {}
for i = 1, select("#", ...) do
parts[i] = tostring(select(i, ...))
end
output[#output+1] = table.concat(parts, "\t")
end값 반환
샌드박스 코드가 값을 반환하도록 하려면 컴파일된 청크를 함수로 호출하고 반환 값을 캡처합니다.
local fn = load("return math.sqrt(144)", "user", "t", env)
if fn then
local ok, result = pcall(fn)
print(ok, result) -- true 12.0
end메타메서드 악용 차단
필드 제한을 우회하지 못하도록 샌드박스 코드가 메타테이블이나 rawget/rawset에 대한 참조를 얻지 못하게 해야 합니다.
문자열 길이 제한
문자열 연산을 재정의하여 출력 길이를 제한하고 거대한 문자열 할당을 통한 DoS를 방지합니다.
debug.sethook를 사용한 리소스 제한
폭주하는 코드를 종료할 수 있도록 명령어 카운터 훅을 추가합니다.
local function sandboxWithLimit(code, env, maxOps)
local ops = 0
debug.sethook(function()
ops = ops + 1
if ops > maxOps then error("Instruction limit exceeded") end
end, "", 100)
local result = table.pack(runSandboxed(code, env))
debug.sethook()
return table.unpack(result, 1, result.n)
end샌드박스 테스트
알려진 탈출 경로를 시도하는 테스트를 작성합니다. _G에 접근하고, load를 호출하고, debug를 사용하는 시도가 모두 실패하는지 확인합니다.
알려진 탈출 경로
일반적인 탈출 경로는 다음과 같습니다. string.rep("x",2^30)(메모리 DoS), 표준 객체의 ({}).__index, 문자열 메타테이블을 통한 debug, package.loaded를 통한 io입니다.
샌드박스 관련 질문
샌드박스에 load 또는 dofile을 포함하지 않는 이유는 무엇인가요?
요약: 제한된 샌드박스 구축
사용자 지정 env 테이블에는 안전한 함수만 허용 목록으로 지정합니다. load(code, name, "t", env)를 사용합니다. debug.sethook로 명령어 수를 셉니다. 탈출 경로를 테스트합니다. load, dofile, debug 또는 전역 테이블 접근은 절대 포함하지 않습니다.
자주 묻는 질문
“제한된 샌드박스 만들기” 강의는 무료인가요?
네 — “제한된 샌드박스 만들기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Lua Academy 강의 전체를 잠금 해제할 수 있습니다. Lua Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“제한된 샌드박스 만들기”에서 뭘 배우나요?
안전한 _ENV 허용 목록을 만들고 load()로 신뢰할 수 없는 코드를 실행합니다. 브라우저에서 직접 실행하는 실습 코드로 Lua Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Lua Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Lua Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“제한된 샌드박스 만들기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Lua Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Lua Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- Lua 5.2+의 _ENV 모델
- 제한된 샌드박스 만들기
- 샌드박스 탈출 방지
- 리소스 제한과 계측