0Pricing
Lua Academy · Урок

Создание ограниченной песочницы

Создайте безопасный список разрешённых элементов _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 — локальная установка не требуется.

Все уроки этого курса

  1. Модель _ENV в Lua 5.2+
  2. Создание ограниченной песочницы
  3. Предотвращение выхода из песочницы
  4. Ограничения ресурсов и инструментирование
← Назад к Lua Academy