Skip to content

Commit 8c99f22

Browse files
committedDec 18, 2021
Don't let HTTP API pass through untrusted function
This has been a problem since the first day, oops.
1 parent 8472141 commit 8c99f22

File tree

4 files changed

+27
-6
lines changed

4 files changed

+27
-6
lines changed
 

Diff for: ‎builtin/game/misc.lua

+3-2
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ end
250250

251251
-- HTTP callback interface
252252

253-
function core.http_add_fetch(httpenv)
253+
core.set_http_api_lua(function(httpenv)
254254
httpenv.fetch = function(req, callback)
255255
local handle = httpenv.fetch_async(req)
256256

@@ -266,7 +266,8 @@ function core.http_add_fetch(httpenv)
266266
end
267267

268268
return httpenv
269-
end
269+
end)
270+
core.set_http_api_lua = nil
270271

271272

272273
function core.close_formspec(player_name, formname)

Diff for: ‎src/script/common/c_internal.h

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ extern "C" {
5454
#define CUSTOM_RIDX_GLOBALS_BACKUP (CUSTOM_RIDX_BASE + 1)
5555
#define CUSTOM_RIDX_CURRENT_MOD_NAME (CUSTOM_RIDX_BASE + 2)
5656
#define CUSTOM_RIDX_BACKTRACE (CUSTOM_RIDX_BASE + 3)
57+
#define CUSTOM_RIDX_HTTP_API_LUA (CUSTOM_RIDX_BASE + 4)
58+
5759

5860
// Determine if CUSTOM_RIDX_SCRIPTAPI will hold a light or full userdata
5961
#if defined(__aarch64__) && USE_LUAJIT

Diff for: ‎src/script/lua_api/l_http.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,20 @@ int ModApiHttp::l_http_fetch_async_get(lua_State *L)
163163
return 1;
164164
}
165165

166+
int ModApiHttp::l_set_http_api_lua(lua_State *L)
167+
{
168+
NO_MAP_LOCK_REQUIRED;
169+
170+
// This is called by builtin to give us a function that will later
171+
// populate the http_api table with additional method(s).
172+
// We need this because access to the HTTP api is security-relevant and
173+
// any mod could just mess with a global variable.
174+
luaL_checktype(L, 1, LUA_TFUNCTION);
175+
lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA);
176+
177+
return 0;
178+
}
179+
166180
int ModApiHttp::l_request_http_api(lua_State *L)
167181
{
168182
NO_MAP_LOCK_REQUIRED;
@@ -205,16 +219,16 @@ int ModApiHttp::l_request_http_api(lua_State *L)
205219
return 1;
206220
}
207221

208-
lua_getglobal(L, "core");
209-
lua_getfield(L, -1, "http_add_fetch");
222+
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA);
223+
assert(lua_isfunction(L, -1));
210224

211225
lua_newtable(L);
212226
HTTP_API(fetch_async);
213227
HTTP_API(fetch_async_get);
214228

215229
// Stack now looks like this:
216-
// <core.http_add_fetch> <table with fetch_async, fetch_async_get>
217-
// Now call core.http_add_fetch to append .fetch(request, callback) to table
230+
// <function> <table with fetch_async, fetch_async_get>
231+
// Now call it to append .fetch(request, callback) to table
218232
lua_call(L, 1, 1);
219233

220234
return 1;
@@ -247,6 +261,7 @@ void ModApiHttp::Initialize(lua_State *L, int top)
247261
API_FCT(get_http_api);
248262
} else {
249263
API_FCT(request_http_api);
264+
API_FCT(set_http_api_lua);
250265
}
251266

252267
#endif

Diff for: ‎src/script/lua_api/l_http.h

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ class ModApiHttp : public ModApiBase {
4141
// http_fetch_async_get(handle)
4242
static int l_http_fetch_async_get(lua_State *L);
4343

44+
// set_http_api_lua() [internal]
45+
static int l_set_http_api_lua(lua_State *L);
46+
4447
// request_http_api()
4548
static int l_request_http_api(lua_State *L);
4649

0 commit comments

Comments
 (0)
Please sign in to comment.