Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Don't let HTTP API pass through untrusted function
This has been a problem since the first day, oops.
  • Loading branch information
sfan5 committed Dec 18, 2021
1 parent 8472141 commit 8c99f22
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
5 changes: 3 additions & 2 deletions builtin/game/misc.lua
Expand Up @@ -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)

Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions src/script/common/c_internal.h
Expand Up @@ -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
Expand Down
23 changes: 19 additions & 4 deletions src/script/lua_api/l_http.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/script/lua_api/l_http.h
Expand Up @@ -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);

Expand Down

0 comments on commit 8c99f22

Please sign in to comment.