Require minetest.request_http_api to be called from the mod's main scope
authorJeija <norrepli@gmail.com>
Thu, 25 Feb 2016 09:22:54 +0000 (10:22 +0100)
committerest31 <MTest31@outlook.com>
Thu, 3 Mar 2016 21:42:00 +0000 (22:42 +0100)
Fixes #3764

doc/lua_api.txt
src/script/lua_api/l_http.cpp

index aee3674d05617453350fc4caca2e9896e16413a5..8c879c96ebf27540c097a4016e8b2b5453d03bb6 100644 (file)
@@ -2337,7 +2337,7 @@ These functions return the leftover itemstack.
       otherwise returns `nil`.
     * The returned table contains the functions `fetch`, `fetch_async` and `fetch_async_get`
       described below.
-    * Only works at init time.
+    * Only works at init time and must be called from the mod's main scope (not from a function).
     * Function only exists if minetest server was built with cURL support.
     * **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED TABLE, STORE IT IN
       A LOCAL VARIABLE!**
index b0357e3e0cf291c1b3958a8532ac45c34afe52e8..8bd39b6ed158f41ce1aa2d70fd3fe4d38b1c5e39 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "lua_api/l_http.h"
 #include "httpfetch.h"
 #include "settings.h"
+#include "debug.h"
 #include "log.h"
 
 #include <algorithm>
@@ -130,11 +131,27 @@ int ModApiHttp::l_request_http_api(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
 
+       // We have to make sure that this function is being called directly by
+       // a mod, otherwise a malicious mod could override this function and
+       // steal its return value.
+       lua_Debug info;
+
+       // Make sure there's only one item below this function on the stack...
+       if (lua_getstack(L, 2, &info)) {
+               return 0;
+       }
+       FATAL_ERROR_IF(!lua_getstack(L, 1, &info), "lua_getstack() failed");
+       FATAL_ERROR_IF(!lua_getinfo(L, "S", &info), "lua_getinfo() failed");
+
+       // ...and that that item is the main file scope.
+       if (strcmp(info.what, "main") != 0) {
+               return 0;
+       }
+
        // Mod must be listed in secure.http_mods or secure.trusted_mods
        lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
        if (!lua_isstring(L, -1)) {
-               lua_pushnil(L);
-               return 1;
+               return 0;
        }
 
        const char *mod_name = lua_tostring(L, -1);