From 6ea1e39ee44cca4b689c01ab095cf41305f2e347 Mon Sep 17 00:00:00 2001 From: peace-maker Date: Sun, 7 Mar 2021 23:33:33 +0100 Subject: [PATCH] core/sm: Harden plugin loading path requirements (#1437) * Harden plugin loading path requirements Restrict loading of plugins to the `sourcemod/plugins` folder and require the `.smx` file extension. Symlinks inside the `plugins` folder are fine. This behavior was abused as part of justCTF 2020 in the PainterHell challenge by cypis. Thank you! * Restrict extension loading to extensions folder * Add NULL file extension check in LoadExtension hi @KyleS --- core/logic/ExtensionSys.cpp | 8 +++++++- core/logic/PluginSys.cpp | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/logic/ExtensionSys.cpp b/core/logic/ExtensionSys.cpp index d1df7cfc..2a746099 100644 --- a/core/logic/ExtensionSys.cpp +++ b/core/logic/ExtensionSys.cpp @@ -631,9 +631,15 @@ IExtension *CExtensionManager::FindExtensionByName(const char *ext) IExtension *CExtensionManager::LoadExtension(const char *file, char *error, size_t maxlength) { + if (strstr(file, "..") != NULL) + { + ke::SafeStrcpy(error, maxlength, "Cannot load extensions outside the \"extensions\" folder."); + return NULL; + } + /* Remove platform extension if it's there. Compat hack. */ const char *ext = libsys->GetFileExtension(file); - if (strcmp(ext, PLATFORM_LIB_EXT) == 0) + if (ext && strcmp(ext, PLATFORM_LIB_EXT) == 0) { char path2[PLATFORM_MAX_PATH]; ke::SafeStrcpy(path2, sizeof(path2), file); diff --git a/core/logic/PluginSys.cpp b/core/logic/PluginSys.cpp index e6cd1dcc..649e8429 100644 --- a/core/logic/PluginSys.cpp +++ b/core/logic/PluginSys.cpp @@ -974,6 +974,20 @@ IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType typ LoadRes res; *wasloaded = false; + + if (strstr(path, "..") != NULL) + { + ke::SafeStrcpy(error, maxlength, "Cannot load plugins outside the \"plugins\" folder"); + return NULL; + } + + const char *ext = libsys->GetFileExtension(path); + if (!ext || strcmp(ext, "smx") != 0) + { + ke::SafeStrcpy(error, maxlength, "Plugin files must have the \".smx\" file extension"); + return NULL; + } + if ((res=LoadPlugin(&pl, path, true, PluginType_MapUpdated)) == LoadRes_Failure) { ke::SafeStrcpy(error, maxlength, pl->GetErrorMsg());