diff --git a/freqtrade/rpc/api_server/web_ui.py b/freqtrade/rpc/api_server/web_ui.py index 76c8ed8f2..0168930cf 100644 --- a/freqtrade/rpc/api_server/web_ui.py +++ b/freqtrade/rpc/api_server/web_ui.py @@ -37,8 +37,11 @@ async def index_html(rest_of_path: str): if rest_of_path.startswith('api') or rest_of_path.startswith('.'): raise HTTPException(status_code=404, detail="Not Found") uibase = Path(__file__).parent / 'ui/installed/' - if (uibase / rest_of_path).is_file(): - return FileResponse(str(uibase / rest_of_path)) + filename = uibase / rest_of_path + # It's security relevant to check "relative_to". + # Without this, Directory-traversal is possible. + if filename.is_file() and filename.is_relative_to(uibase): + return FileResponse(str(filename)) index_file = uibase / 'index.html' if not index_file.is_file(): diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index edf5ce3c5..3d02e8188 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -109,6 +109,7 @@ def test_api_ui_fallback(botclient): rc = client_get(client, "/something") assert rc.status_code == 200 + # Test directory traversal rc = client_get(client, '%2F%2F%2Fetc/passwd') assert rc.status_code == 200 assert '`freqtrade install-ui`' in rc.text