1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Refactor how script api reads current mod name

This is to prevent future mistakes and make it clearer whether
the mod name can be trusted depending on how it is retrieved.
This commit is contained in:
sfan5 2024-02-14 13:29:53 +01:00
parent cb5fa56e17
commit ce97210eb1
8 changed files with 88 additions and 78 deletions

View file

@ -555,10 +555,9 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
return false;
// Get mod name
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
if (lua_isstring(L, -1)) {
std::string mod_name = readParam<std::string>(L, -1);
// FIXME: insecure = problem here?
std::string mod_name = ScriptApiBase::getCurrentModNameInsecure(L);
if (!mod_name.empty()) {
// Builtin can access anything
if (mod_name == BUILTIN_MOD_NAME) {
if (write_allowed) *write_allowed = true;
@ -578,7 +577,6 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
}
}
}
lua_pop(L, 1); // Pop mod name
// Allow read-only access to game directory
if (!write_required) {
@ -629,26 +627,9 @@ bool ScriptApiSecurity::checkWhitelisted(lua_State *L, const std::string &settin
{
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))
std::string mod_name = ScriptApiBase::getCurrentModName(L);
if (mod_name.empty())
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());