Bytecode Breakdown: Unraveling Factorio's Lua Security Flaws
A deep dive into a remote code execution exploit in Factorio’s Lua sandbox highlights how accepting untrusted bytecode—rather than validated source—can completely break game client security. Commenters contrast Lua’s non‑verifiable bytecode with designs like JVM, .NET, WASM, and BPF, argue that JITs and bytecode interpreters are inherently hard to harden, and note that many platforms now disable direct bytecode loading and dangerous standard libraries by default. The thread broadens into concerns about game security in general, the limits of sandboxing and configuration flags, and why projects like Roblox’s Luau and modern browsers invest so heavily in tightly constrained, speculatively safe execution environments.
Scope of the Exploit & Lua Bytecode Design
- Exploit hinges on Factorio allowing loading of raw Lua bytecode from untrusted sources (servers/mods).
- Commenters stress that Lua’s bytecode was designed for execution speed, not static safety verification.
- Some compare this to giving web pages access to a JS engine’s internal bytecode rather than JS source.
- Several note that Lua’s own docs already warn that loading untrusted binary chunks is unsafe.
Bytecode vs JIT and Verifiability
- Debate over conflating bytecode with JIT:
- One side argues JIT adds extra attack surface (RWX memory, speculation issues, Spectre/Meltdown).
- Others point out this exploit is purely about malicious bytecode, not JIT.
- Examples like JVM, .NET, WASM, and BPF are cited as “designed-to-be-verifiable” bytecodes.
- Discussion on how much easier static verification is for simpler, stack-based or strongly-typed bytecodes versus Lua’s design.
Factorio’s Response and Responsibility
- Links to Factorio commits show remediation: essentially disabling bytecode loading and tightening APIs like
load. - Some are surprised Factorio implemented its own verifier despite upstream abandoning one as too hard.
- There is criticism of “security through obscurity” when changes weren’t clearly documented; others note most players auto-update anyway.
Sandboxing Lua and Best Practices
- Strong consensus: never allow untrusted Lua bytecode; only accept source.
- Common advice: disable debug, IO, OS libraries; be very cautious about sandboxing in general.
- Historical parallels from other games (Roblox, Garry’s Mod, Company of Heroes) show repeated failures around Lua bytecode and sandboxes.
- Luau is cited as an example that bans untrusted bytecode and provides stronger sandboxing guarantees.
Game Architecture, Multiplayer, and Isolation
- Factorio syncs simulation by replaying inputs on all clients, so Lua scripts must run identically everywhere; syncing only results would explode bandwidth.
- Some suggest Firecracker-like VM or strong OS-level isolation for untrusted code, but portability and performance are concerns.
- Broader sentiment: treat networked games as insecure clients; consider isolating gaming machines or sandboxes.
Why Lua Instead of JavaScript?
- Lua is seen as much easier to embed, with a small, integration-focused design.
- JS engines (especially browser ones) are considered heavier, more complex, and historically harder to integrate, despite their stronger hardening.