|
| 1 | +package dev.amble.lib.script.lua; |
| 2 | + |
| 3 | +import org.luaj.vm2.Globals; |
| 4 | +import org.luaj.vm2.LoadState; |
| 5 | +import org.luaj.vm2.LuaValue; |
| 6 | +import org.luaj.vm2.compiler.LuaC; |
| 7 | +import org.luaj.vm2.lib.*; |
| 8 | +import org.luaj.vm2.lib.jse.JseBaseLib; |
| 9 | +import org.luaj.vm2.lib.jse.JseMathLib; |
| 10 | + |
| 11 | +/** |
| 12 | + * Creates a sandboxed Lua environment that prevents access to dangerous APIs. |
| 13 | + * <p> |
| 14 | + * This specifically excludes: |
| 15 | + * <ul> |
| 16 | + * <li>luajava - Prevents arbitrary Java class access and code execution</li> |
| 17 | + * <li>os library - Prevents system command execution and file operations</li> |
| 18 | + * <li>io library - Prevents file system access</li> |
| 19 | + * <li>debug library - Prevents environment manipulation and introspection attacks</li> |
| 20 | + * <li>load/loadfile/loadstring with bytecode - Prevents bytecode injection</li> |
| 21 | + * </ul> |
| 22 | + */ |
| 23 | +public final class SandboxedGlobals { |
| 24 | + |
| 25 | + private SandboxedGlobals() { |
| 26 | + // Utility class |
| 27 | + } |
| 28 | + |
| 29 | + /** |
| 30 | + * Creates a new sandboxed Lua globals environment. |
| 31 | + * This environment is safe to use with untrusted scripts. |
| 32 | + * |
| 33 | + * @return A new sandboxed Globals instance |
| 34 | + */ |
| 35 | + public static Globals create() { |
| 36 | + Globals globals = new Globals(); |
| 37 | + |
| 38 | + // Install safe base libraries |
| 39 | + globals.load(new JseBaseLib()); // Basic functions (print, type, etc.) - but we'll remove dangerous ones |
| 40 | + globals.load(new PackageLib()); // Package/module system |
| 41 | + globals.load(new Bit32Lib()); // Bit operations |
| 42 | + globals.load(new TableLib()); // Table manipulation |
| 43 | + globals.load(new StringLib()); // String manipulation |
| 44 | + globals.load(new JseMathLib()); // Math functions |
| 45 | + |
| 46 | + // Install the compiler so scripts can be loaded |
| 47 | + LoadState.install(globals); |
| 48 | + LuaC.install(globals); |
| 49 | + |
| 50 | + // Remove dangerous functions from base library |
| 51 | + removeDangerousFunctions(globals); |
| 52 | + |
| 53 | + return globals; |
| 54 | + } |
| 55 | + |
| 56 | + /** |
| 57 | + * Removes dangerous functions that could be used to escape the sandbox. |
| 58 | + */ |
| 59 | + private static void removeDangerousFunctions(Globals globals) { |
| 60 | + // Remove functions that can load arbitrary code |
| 61 | + globals.set("dofile", LuaValue.NIL); // Can load files from disk |
| 62 | + globals.set("loadfile", LuaValue.NIL); // Can load files from disk |
| 63 | + |
| 64 | + // Note: We keep 'load' and 'loadstring' since they can only load Lua source code |
| 65 | + // (not bytecode) when LuaC is the only compiler installed, making them relatively safe. |
| 66 | + // However, if you want maximum security, uncomment these: |
| 67 | + // globals.set("load", LuaValue.NIL); |
| 68 | + // globals.set("loadstring", LuaValue.NIL); |
| 69 | + |
| 70 | + // Remove the package.loadlib function which can load native libraries |
| 71 | + LuaValue pkg = globals.get("package"); |
| 72 | + if (pkg.istable()) { |
| 73 | + pkg.set("loadlib", LuaValue.NIL); |
| 74 | + } |
| 75 | + } |
| 76 | +} |
| 77 | + |
0 commit comments