Skip to content
Permalink
Browse files
Isolate library tables between sandbox and insecure env
  • Loading branch information
sfan5 committed Apr 18, 2021
1 parent 52c0384 commit 623f0a8613bd8677e259366a1d540deedb9d2302
Showing with 43 additions and 1 deletion.
  1. +43 −1 src/script/cpp_api/s_security.cpp
@@ -45,6 +45,21 @@ static inline void copy_safe(lua_State *L, const char *list[], unsigned len, int
}
}

static void shallow_copy_table(lua_State *L, int from=-2, int to=-1)
{
if (from < 0) from = lua_gettop(L) + from + 1;
if (to < 0) to = lua_gettop(L) + to + 1;
lua_pushnil(L);
while (lua_next(L, from) != 0) {
assert(lua_type(L, -1) != LUA_TTABLE);
// duplicate key and value for lua_rawset
lua_pushvalue(L, -2);
lua_pushvalue(L, -2);
lua_rawset(L, to);
lua_pop(L, 1);
}
}

// Pushes the original version of a library function on the stack, from the old version
static inline void push_original(lua_State *L, const char *lib, const char *func)
{
@@ -83,7 +98,10 @@ void ScriptApiSecurity::initializeSecurity()
"unpack",
"_VERSION",
"xpcall",
// Completely safe libraries
};
static const char *whitelist_tables[] = {
// These libraries are completely safe BUT we need to duplicate their table
// to ensure the sandbox can't affect the insecure env
"coroutine",
"string",
"table",
@@ -167,6 +185,17 @@ void ScriptApiSecurity::initializeSecurity()
lua_pop(L, 1);


// Copy safe libraries
for (const char *libname : whitelist_tables) {
lua_getfield(L, old_globals, libname);
lua_newtable(L);
shallow_copy_table(L);

lua_setglobal(L, libname);
lua_pop(L, 1);
}


// Copy safe IO functions
lua_getfield(L, old_globals, "io");
lua_newtable(L);
@@ -222,6 +251,19 @@ void ScriptApiSecurity::initializeSecurity()
#endif

lua_pop(L, 1); // Pop globals_backup


/*
* In addition to copying the tables in whitelist_tables, we also need to
* replace the string metatable. Otherwise old_globals.string would
* be accessible via getmetatable("").__index from inside the sandbox.
*/
lua_pushliteral(L, "");
lua_newtable(L);
lua_getglobal(L, "string");
lua_setfield(L, -2, "__index");
lua_setmetatable(L, -2);
lua_pop(L, 1); // Pop empty string
}

void ScriptApiSecurity::initializeSecurityClient()

0 comments on commit 623f0a8

Please sign in to comment.