Skip to content

Commit 623f0a8

Browse files
committedApr 18, 2021
Isolate library tables between sandbox and insecure env
1 parent 52c0384 commit 623f0a8

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed
 

‎src/script/cpp_api/s_security.cpp

+43-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,21 @@ static inline void copy_safe(lua_State *L, const char *list[], unsigned len, int
4545
}
4646
}
4747

48+
static void shallow_copy_table(lua_State *L, int from=-2, int to=-1)
49+
{
50+
if (from < 0) from = lua_gettop(L) + from + 1;
51+
if (to < 0) to = lua_gettop(L) + to + 1;
52+
lua_pushnil(L);
53+
while (lua_next(L, from) != 0) {
54+
assert(lua_type(L, -1) != LUA_TTABLE);
55+
// duplicate key and value for lua_rawset
56+
lua_pushvalue(L, -2);
57+
lua_pushvalue(L, -2);
58+
lua_rawset(L, to);
59+
lua_pop(L, 1);
60+
}
61+
}
62+
4863
// Pushes the original version of a library function on the stack, from the old version
4964
static inline void push_original(lua_State *L, const char *lib, const char *func)
5065
{
@@ -83,7 +98,10 @@ void ScriptApiSecurity::initializeSecurity()
8398
"unpack",
8499
"_VERSION",
85100
"xpcall",
86-
// Completely safe libraries
101+
};
102+
static const char *whitelist_tables[] = {
103+
// These libraries are completely safe BUT we need to duplicate their table
104+
// to ensure the sandbox can't affect the insecure env
87105
"coroutine",
88106
"string",
89107
"table",
@@ -167,6 +185,17 @@ void ScriptApiSecurity::initializeSecurity()
167185
lua_pop(L, 1);
168186

169187

188+
// Copy safe libraries
189+
for (const char *libname : whitelist_tables) {
190+
lua_getfield(L, old_globals, libname);
191+
lua_newtable(L);
192+
shallow_copy_table(L);
193+
194+
lua_setglobal(L, libname);
195+
lua_pop(L, 1);
196+
}
197+
198+
170199
// Copy safe IO functions
171200
lua_getfield(L, old_globals, "io");
172201
lua_newtable(L);
@@ -222,6 +251,19 @@ void ScriptApiSecurity::initializeSecurity()
222251
#endif
223252

224253
lua_pop(L, 1); // Pop globals_backup
254+
255+
256+
/*
257+
* In addition to copying the tables in whitelist_tables, we also need to
258+
* replace the string metatable. Otherwise old_globals.string would
259+
* be accessible via getmetatable("").__index from inside the sandbox.
260+
*/
261+
lua_pushliteral(L, "");
262+
lua_newtable(L);
263+
lua_getglobal(L, "string");
264+
lua_setfield(L, -2, "__index");
265+
lua_setmetatable(L, -2);
266+
lua_pop(L, 1); // Pop empty string
225267
}
226268

227269
void ScriptApiSecurity::initializeSecurityClient()

0 commit comments

Comments
 (0)
Please sign in to comment.