fix(auth): remove X-User-Id header trust to prevent BOLA (fixes #2065) - #2068
fix(auth): remove X-User-Id header trust to prevent BOLA (fixes #2065)#2068namann5 wants to merge 7 commits into
Conversation
…t BOLA The resolve_owner_id function trusted the X-User-Id header unconditionally for determining the owner identity. This allowed any authenticated user to impersonate any other user by spoofing the header, bypassing all multi-tenant isolation checks (BOLA). Now resolve_owner_id always returns the default owner identity. The owner identity is bound to the authentication mechanism (session cookie / API key) rather than a client-supplied header. This prevents header spoofing attacks while maintaining backward compatibility for single-tenant deployments. Fixes utksh1#2065
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5668e6b31b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
utksh1
left a comment
There was a problem hiding this comment.
Removing the client-controlled owner header is the right security direction, but this breaks required backend-unit and integration checks. Please update the ownership tests and any documented multi-user contract to use an authenticated principal rather than X-User-Id, and add a regression test proving a supplied X-User-Id cannot select another owner.
utksh1
left a comment
There was a problem hiding this comment.
Ignoring X-User-Id is the correct immediate security posture, but this changes owner semantics for every route and currently fails backend-unit and backend-integration. Please add regression tests that prove spoofed headers cannot select another owner, update any intended single-owner expectations, and fix the failing checks before merge.
Update unit and integration tests to reflect the new security model where resolve_owner_id ignores the X-User-Id header and always returns DEFAULT_OWNER_ID. Tests now seed data directly with different owner_ids to verify cross-owner isolation instead of relying on the spoofable header. Added regression tests proving X-User-Id header spoofing cannot select another owner's identity.
…ient The app_client fixture overrides require_api_key to always succeed, causing test_unauthenticated_request_rejected and test_wrong_api_key_rejected to return 200 instead of 401. Added no_auth_app_client fixture that uses real auth for these tests.
|
Hi @utksh1 — I've addressed the review feedback on the X-User-Id removal: Done in prior commits
New in this push
Status
Could you re-review when you get a chance? Thanks! |
|
Update: all CI checks are now green after the latest push (including the frontend checks that were previously blocked by the transient postcss audit advisory). Ready for re-review whenever convenient. |
19d257c to
90eb68c
Compare
|
@utksh1 All admin review comments have been addressed and the branch is rebased onto the latest main (including the undici override fix), so all required checks are green and the PR is mergeable. Requesting re-review. Summary of changes in this PR:esolve_owner_id now ignores the X-User-Id header entirely (falls back to DEFAULT_OWNER_ID), closing the spoofing bypass.
|
Summary
Fixes a critical BOLA vulnerability where
resolve_owner_idtrusted theX-User-Idheader unconditionally, allowing any authenticated user to impersonate any other user.Problem
The
resolve_owner_idfunction inauth.pyderived the owner identity from theX-User-Idheader without any cryptographic binding to the API key or session. Since the deployment uses a single shared API key, any authenticated user could setX-User-Id: victim-userto access, modify, or delete any other user's data (tasks, findings, vault secrets, notification rules, etc.).This also allowed rate limiting bypass by rotating
X-User-Idvalues.Fix
X-User-Idheader trust path fromresolve_owner_idDEFAULT_OWNER_ID("default")Impact
Testing
Fixes #2065