Skip to content

Lua Sandbox AuditΒΆ

Date: 2026-04-09 (Phase 98, SEC-04) Lua version: Lua 5.4 (vendored via mlua 0.11) Status: Audit complete β€” no escape vectors found

Sandbox ConfigurationΒΆ

Moon uses mlua (Rust bindings for Lua 5.4) with a restricted standard library:

File: src/scripting/sandbox.rs

Allowed LibrariesΒΆ

Library Status Justification
base (partial) Allowed type, tostring, tonumber, pcall, error, select, unpack, pairs, ipairs, next
string Allowed String manipulation β€” no I/O
table Allowed Table manipulation β€” no I/O
math Allowed Math functions β€” no I/O
cjson (if available) Allowed JSON encode/decode β€” pure computation

Blocked LibrariesΒΆ

Library Status Risk if exposed
io Blocked Filesystem read/write
os Blocked Command execution, env vars, file ops
debug Blocked Stack inspection, upvalue modification, gc manipulation
package Blocked Module loading from filesystem
loadfile Blocked Load and execute arbitrary Lua files
dofile Blocked Load and execute arbitrary Lua files
load (with file source) Blocked Load bytecode from files
collectgarbage Blocked GC manipulation can cause timing attacks
rawget/rawset Allowed Metatable bypass β€” acceptable for Redis scripting

redis.* APIΒΆ

The sandbox registers these functions:

Function Description Safety
redis.call(cmd, ...) Execute Redis command Safe β€” routes through ACL + command dispatch
redis.pcall(cmd, ...) Protected call (returns error instead of raising) Safe
redis.log(level, msg) Write to Moon's tracing log Safe β€” message is sanitized
redis.error_reply(msg) Return error frame Safe
redis.status_reply(msg) Return status frame Safe

Type ConversionsΒΆ

Lua β†’ Redis Redis β†’ Lua
string β†’ BulkString BulkString β†’ string
number (integer) β†’ Integer Integer β†’ number
boolean β†’ Integer (1/0) Null β†’ false
table (array) β†’ Array Array β†’ table
nil β†’ Null Error β†’ raises Lua error

Resource LimitsΒΆ

Resource Limit Enforcement
Script execution time Configurable timeout (default: 5s) mlua timeout hook
Memory allocation Bounded by server maxmemory Lua allocator hooks (via mlua)
Stack depth Lua default (200 levels) Built-in
Keys accessed Must be declared in EVAL KEYS array Validated before execution

CVE Review (lua54 vendored source)ΒΆ

mlua 0.11 vendors Lua 5.4.7 (latest stable as of 2026-04). Known CVEs:

CVE Affected Status
CVE-2022-33099 Lua < 5.4.4 Fixed in vendored 5.4.7
CVE-2022-28805 Lua < 5.4.4 Fixed in vendored 5.4.7
CVE-2021-44964 Lua < 5.4.4 Fixed in vendored 5.4.7
CVE-2021-43519 Lua < 5.4.4 Fixed in vendored 5.4.7

No open CVEs affecting Lua 5.4.7.

Potential Escape Vectors (Reviewed)ΒΆ

Vector Status Detail
debug.getinfo Blocked Debug library not loaded
package.loadlib Blocked Package library not loaded
os.execute Blocked OS library not loaded
io.open Blocked IO library not loaded
load(bytecode) Restricted Only string source allowed, no file source
string.dump β†’ load Safe Can dump+reload functions but stays within sandbox
coroutine.wrap abuse Safe Coroutine resume/yield bounded by timeout
Metatable __gc abuse Low risk GC finalizers run in sandbox context
redis.call as oracle By design ACL controls which commands are accessible

RecommendationsΒΆ

  1. Monitor mlua releases for security patches to the vendored Lua source.
  2. Consider disabling load entirely β€” EVALSHA covers script caching without runtime compilation.
  3. Add SCRIPT NO-WRITES flag in future β€” allow read-only scripts to skip ACL write checks.
  4. Fuzz the Lua bridge β€” add a cargo-fuzz target that feeds random Lua source to the sandbox.

This audit covers the sandbox configuration as of mlua 0.11 + Lua 5.4.7. Re-audit when upgrading mlua or changing sandbox settings.