Security and Sandboxing in Production
Untrusted scripts accessing the system Restricted _ENV whitelists (Module 30); remove os, io, debug, load, require, package, dofile, loadfile, collectgarbage, string.dump, rawset/metatable functions as needed
Load with mode "t" only; never accept precompiled chunks from untrusted sources Infinite loops (CPU DoS)
Instruction-count hooks (debug.sethook with a count), timeouts in the host, separate processes
Custom allocator with limits (lua_setallocf / lua_newstate), process limits String metatable escape
("").__index exposes the string table: don't expose getmetatable in sandboxes, or protect the string metatable
Limit input sizes; some patterns are exponential (e.g., nested .-) Injection (shell, SQL)
Avoid os.execute/io.popen with user input; use parameterized queries (LuaSQL prepared statements, pgmoon escaping)
Validate inputs; keep Redis scripts short; use ngx.quote_sql_str, sanitize headers Game clients (Roblox, mods)
Never trust the client; validate RemoteEvent arguments on the server
Pin rock versions, review rockspecs/sources Production embedding often runs untrusted scripts in separate lua_States (cheap) per tenant or script, which isolates globals and memory accounting.