aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/script/cpp_api/s_security.cpp33
-rw-r--r--src/script/cpp_api/s_security.h14
-rw-r--r--src/script/lua_api/l_http.cpp39
-rw-r--r--src/script/lua_api/l_util.cpp32
4 files changed, 46 insertions, 72 deletions
diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp
index 11c277839..ccd1214e3 100644
--- a/src/script/cpp_api/s_security.cpp
+++ b/src/script/cpp_api/s_security.cpp
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cerrno>
#include <string>
+#include <algorithm>
#include <iostream>
@@ -604,6 +605,38 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
return false;
}
+bool ScriptApiSecurity::checkWhitelisted(lua_State *L, const std::string &setting)
+{
+ assert(str_starts_with(setting, "secure."));
+
+ // 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 false;
+ 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 false;
+
+ // 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))
+ return false;
+ std::string mod_name = readParam<std::string>(L, -1);
+
+ std::string value = g_settings->get(setting);
+ value.erase(std::remove(value.begin(), value.end(), ' '), value.end());
+ auto mod_list = str_split(value, ',');
+
+ return CONTAINS(mod_list, mod_name);
+}
+
int ScriptApiSecurity::sl_g_dofile(lua_State *L)
{
diff --git a/src/script/cpp_api/s_security.h b/src/script/cpp_api/s_security.h
index 73e763548..619bf824f 100644
--- a/src/script/cpp_api/s_security.h
+++ b/src/script/cpp_api/s_security.h
@@ -40,11 +40,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class ScriptApiSecurity : virtual public ScriptApiBase
{
public:
- int getThread(lua_State *L);
- // creates an empty Lua environment
- void createEmptyEnv(lua_State *L);
- // sets the enviroment to the table thats on top of the stack
- void setLuaEnv(lua_State *L, int thread);
// Sets up security on the ScriptApi's Lua state
void initializeSecurity();
void initializeSecurityClient();
@@ -57,8 +52,17 @@ public:
// Checks if mods are allowed to read (and optionally write) to the path
static bool checkPath(lua_State *L, const char *path, bool write_required,
bool *write_allowed=NULL);
+ // Check if mod is whitelisted in the given setting
+ // This additionally checks that the mod's main file scope is executing.
+ static bool checkWhitelisted(lua_State *L, const std::string &setting);
private:
+ int getThread(lua_State *L);
+ // sets the enviroment to the table thats on top of the stack
+ void setLuaEnv(lua_State *L, int thread);
+ // creates an empty Lua environment
+ void createEmptyEnv(lua_State *L);
+
// Syntax: "sl_" <Library name or 'g' (global)> '_' <Function name>
// (sl stands for Secure Lua)
diff --git a/src/script/lua_api/l_http.cpp b/src/script/lua_api/l_http.cpp
index b385b698c..bd359b3cc 100644
--- a/src/script/lua_api/l_http.cpp
+++ b/src/script/lua_api/l_http.cpp
@@ -21,14 +21,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/c_converter.h"
#include "common/c_content.h"
#include "lua_api/l_http.h"
+#include "cpp_api/s_security.h"
#include "httpfetch.h"
#include "settings.h"
#include "debug.h"
#include "log.h"
-#include <algorithm>
#include <iomanip>
-#include <cctype>
#define HTTP_API(name) \
lua_pushstring(L, #name); \
@@ -181,40 +180,8 @@ 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)) {
- return 0;
- }
-
- std::string mod_name = readParam<std::string>(L, -1);
- std::string http_mods = g_settings->get("secure.http_mods");
- http_mods.erase(std::remove(http_mods.begin(), http_mods.end(), ' '), http_mods.end());
- std::vector<std::string> mod_list_http = str_split(http_mods, ',');
-
- std::string trusted_mods = g_settings->get("secure.trusted_mods");
- trusted_mods.erase(std::remove(trusted_mods.begin(), trusted_mods.end(), ' '), trusted_mods.end());
- std::vector<std::string> mod_list_trusted = str_split(trusted_mods, ',');
-
- mod_list_http.insert(mod_list_http.end(), mod_list_trusted.begin(), mod_list_trusted.end());
- if (std::find(mod_list_http.begin(), mod_list_http.end(), mod_name) == mod_list_http.end()) {
+ if (!ScriptApiSecurity::checkWhitelisted(L, "secure.http_mods") &&
+ !ScriptApiSecurity::checkWhitelisted(L, "secure.trusted_mods")) {
lua_pushnil(L);
return 1;
}
diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp
index 528d9c6dd..b04f26fda 100644
--- a/src/script/lua_api/l_util.cpp
+++ b/src/script/lua_api/l_util.cpp
@@ -41,7 +41,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/hex.h"
#include "util/sha1.h"
#include "util/png.h"
-#include <algorithm>
#include <cstdio>
// log([level,] text)
@@ -444,36 +443,7 @@ int ModApiUtil::l_request_insecure_environment(lua_State *L)
return 1;
}
- // 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;
- }
-
- // Get mod name
- lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
- if (!lua_isstring(L, -1)) {
- return 0;
- }
-
- // Check secure.trusted_mods
- std::string mod_name = readParam<std::string>(L, -1);
- std::string trusted_mods = g_settings->get("secure.trusted_mods");
- trusted_mods.erase(std::remove_if(trusted_mods.begin(),
- trusted_mods.end(), static_cast<int(*)(int)>(&std::isspace)),
- trusted_mods.end());
- std::vector<std::string> mod_list = str_split(trusted_mods, ',');
- if (std::find(mod_list.begin(), mod_list.end(), mod_name) ==
- mod_list.end()) {
+ if (!ScriptApiSecurity::checkWhitelisted(L, "secure.trusted_mods")) {
return 0;
}