diff --git a/splunklib/searchcommands/environment.py b/splunklib/searchcommands/environment.py index 83ee939f4..5dec95e02 100644 --- a/splunklib/searchcommands/environment.py +++ b/splunklib/searchcommands/environment.py @@ -97,6 +97,12 @@ def configure_logging(logger_name, filename=None): global _current_logging_configuration_file filename = path.realpath(filename) + app_root_real = path.realpath(app_root) + if path.commonpath([filename, app_root_real]) != app_root_real: # pyright: ignore[reportUnknownArgumentType] + raise ValueError( + f'Logging configuration file "{filename}" is outside the app directory' + ) + if filename != _current_logging_configuration_file: working_directory = getcwd() chdir(app_root) diff --git a/tests/unit/searchcommands/test_builtin_options.py b/tests/unit/searchcommands/test_builtin_options.py index 911321251..dd18c0589 100644 --- a/tests/unit/searchcommands/test_builtin_options.py +++ b/tests/unit/searchcommands/test_builtin_options.py @@ -137,6 +137,30 @@ def test_logging_configuration(self): f"Expected ValueError, but logging_configuration={command.logging_configuration}" ) + # logging_configuration raises a value error for an existing absolute path outside the app directory (RCE guard) + try: + command.logging_configuration = os.path.join(package_directory, "__init__.py") + except ValueError: + pass + except BaseException as e: + pytest.fail(f"Expected ValueError, but {type(e)} was raised") + else: + pytest.fail( + f"Expected ValueError, but logging_configuration={command.logging_configuration}" + ) + + # logging_configuration raises a value error when a relative path traverses outside the app directory (RCE guard) + try: + command.logging_configuration = os.path.join("..", "..", "..", "__init__.py") + except ValueError: + pass + except BaseException as e: + pytest.fail(f"Expected ValueError, but {type(e)} was raised") + else: + pytest.fail( + f"Expected ValueError, but logging_configuration={command.logging_configuration}" + ) + def test_logging_level(self): rebase_environment("app_without_logging_configuration") command = StubbedSearchCommand()