diff --git a/CHANGELOG.md b/CHANGELOG.md index b75a37ce..4ebc78bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.1.9 + +### Security + +- **Avoid reflecting invalid API keys**: authentication failures now return a generic error message instead of including the submitted credential in the response and request logs. + ## 0.1.8 ### Features diff --git a/prepline_general/api/__version__.py b/prepline_general/api/__version__.py index 93b52aec..4eeb8fc3 100644 --- a/prepline_general/api/__version__.py +++ b/prepline_general/api/__version__.py @@ -1 +1 @@ -__version__ = "0.1.8" # pragma: no cover +__version__ = "0.1.9" # pragma: no cover diff --git a/prepline_general/api/general.py b/prepline_general/api/general.py index 8a7b3cb2..2b4a46e8 100644 --- a/prepline_general/api/general.py +++ b/prepline_general/api/general.py @@ -654,7 +654,7 @@ def general_partition( api_key = request.headers.get("unstructured-api-key") if api_key != api_key_env: raise HTTPException( - detail=f"API key {api_key} is invalid", status_code=status.HTTP_401_UNAUTHORIZED + detail="API key is invalid", status_code=status.HTTP_401_UNAUTHORIZED ) accept_type = request.headers.get("Accept") diff --git a/test_general/api/test_app.py b/test_general/api/test_app.py index ff5342d7..9f76207d 100644 --- a/test_general/api/test_app.py +++ b/test_general/api/test_app.py @@ -1,4 +1,5 @@ import io +import logging import os import tempfile import uuid @@ -578,7 +579,7 @@ def test_general_api_returns_503(monkeypatch): assert response.status_code == 503 -def test_general_api_returns_401(monkeypatch): +def test_general_api_returns_401(monkeypatch, caplog): """ When UNSTRUCTURED_API_KEY is set, return a 401 if the unstructured-api-key header does not match """ @@ -594,15 +595,16 @@ def test_general_api_returns_401(monkeypatch): assert response.status_code == 200 - client = TestClient(app) - test_file = Path("sample-docs") / "fake-xml.xml" - response = client.post( - MAIN_API_ROUTE, - files=[("files", (str(test_file), open(test_file, "rb")))], - headers={"unstructured-api-key": "helloworld"}, - ) + with caplog.at_level(logging.ERROR, logger="unstructured_api"): + response = client.post( + MAIN_API_ROUTE, + files=[("files", (str(test_file), open(test_file, "rb")))], + headers={"unstructured-api-key": "helloworld"}, + ) assert response.status_code == 401 + assert response.json() == {"detail": "API key is invalid"} + assert "helloworld" not in caplog.text class MockResponse: