Skip to content

Commit bf900cd

Browse files
committed
wip security fix
1 parent 4209380 commit bf900cd

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

src/main/java/dev/amble/lib/script/AbstractScriptManager.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
import dev.amble.lib.AmbleKit;
44
import dev.amble.lib.script.lua.LuaBinder;
55
import dev.amble.lib.script.lua.MinecraftData;
6+
import dev.amble.lib.script.lua.SandboxedGlobals;
67
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
78
import net.minecraft.resource.Resource;
89
import net.minecraft.resource.ResourceManager;
910
import net.minecraft.util.Identifier;
1011
import org.luaj.vm2.Globals;
1112
import org.luaj.vm2.LuaValue;
12-
import org.luaj.vm2.lib.jse.JsePlatform;
1313

1414
import java.io.InputStreamReader;
1515
import java.util.HashMap;
@@ -72,7 +72,8 @@ public LuaScript load(Identifier id, ResourceManager manager) {
7272
return cache.computeIfAbsent(id, key -> {
7373
try {
7474
Resource res = manager.getResource(key).orElseThrow();
75-
Globals globals = JsePlatform.standardGlobals();
75+
// Use sandboxed globals to prevent access to dangerous APIs like luajava
76+
Globals globals = SandboxedGlobals.create();
7677

7778
// Create and cache the minecraft data for this script
7879
MinecraftData data = createMinecraftData();
@@ -89,7 +90,7 @@ public LuaScript load(Identifier id, ResourceManager manager) {
8990
);
9091
chunk.call();
9192

92-
LuaScript script = new LuaScript(globals);
93+
LuaScript script = new LuaScript(globals);
9394

9495
// Call onRegister when script is first loaded into the manager
9596
if (script.onRegister() != null && !script.onRegister().isnil()) {

src/main/java/dev/amble/lib/script/lua/LuaBinder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ public Varargs invoke(Varargs args) {
343343
}
344344

345345
meta.set("__index", index);
346+
346347
return meta;
347348
}
348349
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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

Comments
 (0)