forked from Mirrorlandia_minetest/minetest
Don't let HTTP API pass through untrusted function
This has been a problem since the first day, oops.
This commit is contained in:
parent
8472141b79
commit
8c99f2232b
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -41,6 +41,9 @@ private:
|
||||
// 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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user