Files
MosisService/docs/LUA-SANDBOX.md

3.8 KiB

Lua Sandbox System

The sandbox provides secure, isolated Lua environments for third-party apps.

Security Features

Feature Implementation
Dangerous globals removed os, io, loadfile, dofile, debug
Memory limits Configurable per-app (default 10MB)
CPU limits Instruction counting with timeout
Bytecode rejected Only source code allowed
Metatables protected Cannot modify string/table metatables
Path traversal blocked ../ and absolute paths rejected

Permission Categories

Category Auto-Grant Examples
Normal Yes storage, network
Dangerous User consent camera, microphone, location, contacts
Signature System apps only system_settings, install_packages

Available APIs

Core APIs (always available):

-- Timers
local id = setTimeout(function() end, 1000)
clearTimeout(id)
local id = setInterval(function() end, 500)
clearInterval(id)

-- JSON
local obj = json.decode('{"key": "value"}')
local str = json.encode({key = "value"})

-- Crypto
local bytes = crypto.randomBytes(16)
local hash = crypto.sha256("data")
local hmac = crypto.hmac("sha256", "key", "data")

Storage APIs (requires storage permission):

-- Virtual filesystem (sandboxed to app directory)
fs.write("data.txt", "content")
local content = fs.read("data.txt")
local files = fs.list("/")
local stat = fs.stat("data.txt")
fs.delete("data.txt")

-- SQLite database
local db = database.open("mydb")
db:execute("CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)")
db:execute("INSERT INTO items (name) VALUES (?)", {"item1"})
local rows = db:query("SELECT * FROM items WHERE id = ?", {1})

Network APIs (requires network permission):

-- HTTP (HTTPS only, private IPs blocked)
local response = http.get("https://api.example.com/data")
local response = http.post("https://api.example.com/data", {
    headers = {["Content-Type"] = "application/json"},
    body = json.encode({key = "value"})
})

-- WebSocket
local ws = websocket.connect("wss://example.com/ws")
ws:send("message")
ws:onMessage(function(data) end)
ws:close()

Hardware APIs (requires dangerous permissions + user gesture):

-- Camera (requires camera permission)
camera.start(function(frame) end)
camera.stop()

-- Microphone (requires microphone permission)
microphone.start(function(samples) end)
microphone.stop()

-- Location (requires location permission)
location.getCurrentPosition(function(pos)
    print(pos.latitude, pos.longitude)
end)

-- Sensors (requires sensors permission)
sensors.subscribe("accelerometer", function(data)
    print(data.x, data.y, data.z)
end)

Running Sandbox Tests

cd sandbox-test
cmake -B build -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
cmake --build build --config Debug
./build/Debug/sandbox-test.exe

# Output: 149 tests, all passing

Test Categories

Category Tests Description
Security 11 Globals removal, bytecode, metatables
Resources 8 Memory, CPU limits, instruction counting
Permissions 7 Normal/dangerous/signature grants
Rate Limiting 6 API call throttling
Timers 7 setTimeout/setInterval behavior
JSON 5 Encode/decode, depth limits
Crypto 4 Random, SHA256, HMAC
VirtualFS 8 Read/write, quotas, traversal
Database 8 SQLite operations, injection prevention
Network 8 URL validation, private IP blocking
WebSocket 7 Connection limits, message size
Hardware 42 Camera, mic, location, sensors, bluetooth
IPC 7 Message bus between apps
Integration 9 Full app lifecycle
Fuzzing 3 Random input crash testing