fix(core): protect the server auth context from reserved provider-data keys#5589
fix(core): protect the server auth context from reserved provider-data keys#5589shaun0927 wants to merge 2 commits intollamastack:mainfrom
Conversation
…a keys. Caller-controlled X-LlamaStack-Provider-Data was able to inject __authenticated_user into the same request-context dictionary used for server-owned auth state. That let get_authenticated_user() return a raw dict and could crash storage-backed request paths that expect a real User. This change keeps the fix narrow: strip the reserved __authenticated_user key when provider-data enters the request context, and ignore non-User values in get_authenticated_user() as defense-in-depth. A focused regression test covers both the middleware boundary and a storage-backed POST path. Constraint: Keep the fix narrow and compatible with existing __test_id-based test-mode flows Rejected: Reject every __-prefixed provider-data key globally | risks breaking existing internal test-mode behavior without maintainer sign-off Confidence: high Scope-risk: narrow Reversibility: clean Directive: If provider-data and server-owned request context are refactored later, preserve the separation between caller-controlled keys and authenticated user state Tested: uv run --python 3.12 pytest tests/unit/server/test_provider_data_reserved_keys.py tests/unit/server/test_test_context_middleware.py tests/unit/core/test_provider_data_context.py tests/unit/utils/test_authorized_sqlstore.py -q Tested: uv run --python 3.12 ruff check src/llama_stack/core/request_headers.py tests/unit/server/test_provider_data_reserved_keys.py tests/unit/server/test_test_context_middleware.py tests/unit/core/test_provider_data_context.py Not-tested: Full repository mypy run on this branch Related: llamastack#5588 Signed-off-by: JunghwanNA <70629228+shaun0927@users.noreply.github.com>
|
Hi @shaun0927! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
thanks, fix works for me. from my understanding, the bug causes 500 responses (when malicious provider-data is sent) but doesn't enable unauthorized access and doesn't crash the server, is that correct? can the 2 unit tests be merged into an existing file like test_test_context_middleware.py or test_provider_data_context.py? don't think we need a separate file for a single bug. |
…st_context_middleware.py Per review feedback on llamastack#5589, merge the two reserved-key regression tests into tests/unit/server/test_test_context_middleware.py instead of keeping them in a separate file. That file already exercises ProviderDataMiddleware with FastAPI + TestClient, so the new cases fit alongside the existing __test_id coverage.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Thanks for the review @derekhiggins!
Yes, that matches what I observed. Concretely:
Done — consolidated into |
What does this PR do?
Closes #5588.
This fixes a request-context boundary bug in
request_headers.py.Today, caller-controlled
X-LlamaStack-Provider-Datacan include the reserved__authenticated_userkey. That key lands in the same dictionary namespace thatthe server uses for authenticated user state, so
get_authenticated_user()canreturn a raw caller-controlled object instead of a validated
User. On currentmain, that is enough to trigger 500s on storage-backed request paths thatexpect
current_user.principal/current_user.attributes.The fix is intentionally narrow:
__authenticated_userkey when provider-data enters therequest context
Uservalues inget_authenticated_user()as defense-in-depthstorage-backed POST path
I kept the scope small on purpose. A broader policy such as rejecting every
__*key in provider-data may also make sense long-term, but that would need aseparate design discussion because the current test-mode flow uses
__test_id.This PR only fixes the validated auth-context collision.
Test Plan
Output:
Output: