Создание ограниченной песочницы
Создайте безопасный список разрешённых элементов _ENV и выполняйте ненадёжный код с помощью load().
«Создание ограниченной песочницы» — бесплатный урок Lua Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения 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 пользовательской функцией, которая добавляет данные в буфер вместо записи в stdout.
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 через метатаблицу строк, io через package.loaded.
Вопрос о песочнице
Почему песочница не включает load или dofile?
Итоги: создание ограниченной песочницы
Включайте в пользовательскую таблицу окружения только безопасные функции из белого списка. Используйте load(code, name, "t", env). Добавьте подсчёт инструкций с помощью debug.sethook. Проверяйте способы обхода. Никогда не включайте load, dofile, debug или доступ к глобальной таблице.
Часто задаваемые вопросы
Урок «Создание ограниченной песочницы» бесплатный?
Да — полный текст урока «Создание ограниченной песочницы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Создание ограниченной песочницы»?
Создайте безопасный список разрешённых элементов _ENV и выполняйте ненадёжный код с помощью load(). Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Создание ограниченной песочницы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Модель _ENV в Lua 5.2+
- Создание ограниченной песочницы
- Предотвращение выхода из песочницы
- Ограничения ресурсов и инструментирование