]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Don't let HTTP API pass through untrusted function
authorsfan5 <sfan5@live.de>
Fri, 17 Dec 2021 17:31:29 +0000 (18:31 +0100)
committersfan5 <sfan5@live.de>
Sat, 18 Dec 2021 19:37:13 +0000 (20:37 +0100)
This has been a problem since the first day, oops.

builtin/game/misc.lua
src/script/common/c_internal.h
src/script/lua_api/l_http.cpp
src/script/lua_api/l_http.h

index ef826eda740d35861d5b3073daeda5e92627640d..e86efc50c37c23b96a988a7e15ca84b2c0ef23c8 100644 (file)
@@ -250,7 +250,7 @@ end
 
 -- HTTP callback interface
 
-function core.http_add_fetch(httpenv)
+core.set_http_api_lua(function(httpenv)
        httpenv.fetch = function(req, callback)
                local handle = httpenv.fetch_async(req)
 
@@ -266,7 +266,8 @@ function core.http_add_fetch(httpenv)
        end
 
        return httpenv
-end
+end)
+core.set_http_api_lua = nil
 
 
 function core.close_formspec(player_name, formname)
index ab2d7b975a89c6af2d923d016dd15772027d5abc..94cfd61fb1912edb4ea76524ada16361c136646c 100644 (file)
@@ -54,6 +54,8 @@ extern "C" {
 #define CUSTOM_RIDX_GLOBALS_BACKUP      (CUSTOM_RIDX_BASE + 1)
 #define CUSTOM_RIDX_CURRENT_MOD_NAME    (CUSTOM_RIDX_BASE + 2)
 #define CUSTOM_RIDX_BACKTRACE           (CUSTOM_RIDX_BASE + 3)
+#define CUSTOM_RIDX_HTTP_API_LUA        (CUSTOM_RIDX_BASE + 4)
+
 
 // Determine if CUSTOM_RIDX_SCRIPTAPI will hold a light or full userdata
 #if defined(__aarch64__) && USE_LUAJIT
index 751ec98376a3dfaf12b9e333ad64003342ed0d0c..b385b698c8a56a576b8512bf9727e60c5e4c8069 100644 (file)
@@ -163,6 +163,20 @@ int ModApiHttp::l_http_fetch_async_get(lua_State *L)
        return 1;
 }
 
+int ModApiHttp::l_set_http_api_lua(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+
+       // This is called by builtin to give us a function that will later
+       // populate the http_api table with additional method(s).
+       // We need this because access to the HTTP api is security-relevant and
+       // any mod could just mess with a global variable.
+       luaL_checktype(L, 1, LUA_TFUNCTION);
+       lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA);
+
+       return 0;
+}
+
 int ModApiHttp::l_request_http_api(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
@@ -205,16 +219,16 @@ int ModApiHttp::l_request_http_api(lua_State *L)
                return 1;
        }
 
-       lua_getglobal(L, "core");
-       lua_getfield(L, -1, "http_add_fetch");
+       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA);
+       assert(lua_isfunction(L, -1));
 
        lua_newtable(L);
        HTTP_API(fetch_async);
        HTTP_API(fetch_async_get);
 
        // Stack now looks like this:
-       // <core.http_add_fetch> <table with fetch_async, fetch_async_get>
-       // Now call core.http_add_fetch to append .fetch(request, callback) to table
+       // <function> <table with fetch_async, fetch_async_get>
+       // Now call it to append .fetch(request, callback) to table
        lua_call(L, 1, 1);
 
        return 1;
@@ -247,6 +261,7 @@ void ModApiHttp::Initialize(lua_State *L, int top)
                API_FCT(get_http_api);
        } else {
                API_FCT(request_http_api);
+               API_FCT(set_http_api_lua);
        }
 
 #endif
index c3a2a52762a2b348f5fc81bd0a25c9eec2673c98..17fa283bac0745f4f3994974f02a579a6d5ecff1 100644 (file)
@@ -41,6 +41,9 @@ class ModApiHttp : public ModApiBase {
        // http_fetch_async_get(handle)
        static int l_http_fetch_async_get(lua_State *L);
 
+       // set_http_api_lua() [internal]
+       static int l_set_http_api_lua(lua_State *L);
+
        // request_http_api()
        static int l_request_http_api(lua_State *L);