Skip to content

fix(security): IDOR in PromptsActivityEndpoint GET - scope project by organization#104990

Merged
dcramer merged 4 commits intomasterfrom
fix/idor-prompts-activity-get
Jan 15, 2026
Merged

fix(security): IDOR in PromptsActivityEndpoint GET - scope project by organization#104990
dcramer merged 4 commits intomasterfrom
fix/idor-prompts-activity-get

Conversation

@dcramer
Copy link
Member

@dcramer dcramer commented Dec 15, 2025

Summary

Fixes IDOR vulnerability in PromptsActivityEndpoint.get() where project_id query parameter was not validated against the organization, allowing users to potentially query prompt activity data using project IDs from other organizations.

Note: The PUT endpoint was already fixed in PR #104920, but the GET endpoint was missed.

Changes

  • Added organization scoping check for project_id in the GET method
  • Added regression test test_idor_get_project_from_different_org

Test plan

  • Regression test added for GET endpoint
  • Existing tests pass (CI)

… organization

The GET endpoint accepted project_id in query params but didn't validate
it belonged to the organization, allowing users to potentially query
prompt activity data using project IDs from other organizations.

Added organization scoping check to the GET method (PUT was already fixed
in PR #104920) and a regression test for the GET endpoint.
@dcramer dcramer requested a review from a team as a code owner December 15, 2025 21:07
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Dec 15, 2025
@dcramer dcramer requested a review from a team December 15, 2025 21:08
Copy link
Member

@markstory markstory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me other than the endpoint parameter consistency.

@dcramer
Copy link
Member Author

dcramer commented Jan 15, 2026

this one is... for some reason, taking a lot of intervention on the agent. def woulda been faster to fix by hand (tho the agent did a great job finding it)

@dcramer
Copy link
Member Author

dcramer commented Jan 15, 2026

Follow-up needed

The organization_id query parameter is now ignored by the GET endpoint (we use the organization from the URL instead). The frontend still passes it in static/app/actionCreators/prompts.tsx:

  • promptsCheck() - line 93
  • makePromptsCheckQueryKey() - line 119
  • batchedPromptsCheck() - line 425

This is harmless but redundant. We should follow up to remove organization_id from the query params in the frontend to clean this up.

- Add organization parameter to method signatures for consistency
- Remove redundant organization_id query param from GET (use URL org)
- Fix fail-open pattern by removing conditional organization check
- Add empty string validation for project_id
- Update tests to reflect new behavior
@dcramer
Copy link
Member Author

dcramer commented Jan 15, 2026

Additional follow-up: Split test classes

The test file tests/sentry/api/endpoints/test_prompts_activity.py should be refactored to split into separate test classes per HTTP method:

  • GetPromptsActivityTest - for GET endpoint tests
  • PutPromptsActivityTest - for PUT endpoint tests

This matches the pattern used elsewhere (e.g., test_organization_search_details.py). This is pre-existing technical debt, not introduced by this PR.

@dcramer dcramer merged commit 65ff1a9 into master Jan 15, 2026
66 checks passed
@dcramer dcramer deleted the fix/idor-prompts-activity-get branch January 15, 2026 20:46
dcramer added a commit that referenced this pull request Jan 15, 2026
The GET endpoint now uses the organization from the URL path, making
the organization_id query parameter redundant. Also adds explicit
error handling when organization is null in promptsCheck().

Follow-up to #104990.
dcramer added a commit that referenced this pull request Jan 15, 2026
Splits the single test class into GetPromptsActivityTest and
PutPromptsActivityTest with a shared base class, matching the pattern
used elsewhere (e.g., test_organization_search_details.py).

Follow-up to #104990.
jasonyuezhang pushed a commit to jasonyuezhang/sentry that referenced this pull request Jan 15, 2026
Splits the single test class into GetPromptsActivityTest and
PutPromptsActivityTest with a shared base class, matching the pattern
used elsewhere (e.g., test_organization_search_details.py).

Follow-up to getsentry#104990.
dcramer added a commit that referenced this pull request Jan 16, 2026
…106414)

Splits the single `PromptsActivityTest` class into separate test classes
per HTTP method, following the pattern used elsewhere (e.g.,
`test_organization_search_details.py`).

Structure:
- `PromptsActivityTestBase` - shared setUp logic
- `GetPromptsActivityTest` - GET endpoint tests (2 tests)
- `PutPromptsActivityTest` - PUT endpoint tests (13 tests)

This addresses pre-existing technical debt, not introduced by the
original PR.

Follow-up to #104990.
BYK pushed a commit that referenced this pull request Jan 19, 2026
…106414)

Splits the single `PromptsActivityTest` class into separate test classes
per HTTP method, following the pattern used elsewhere (e.g.,
`test_organization_search_details.py`).

Structure:
- `PromptsActivityTestBase` - shared setUp logic
- `GetPromptsActivityTest` - GET endpoint tests (2 tests)
- `PutPromptsActivityTest` - PUT endpoint tests (13 tests)

This addresses pre-existing technical debt, not introduced by the
original PR.

Follow-up to #104990.
jaydgoss pushed a commit that referenced this pull request Jan 21, 2026
The GET endpoint now uses the organization from the URL path, making
the organization_id query parameter redundant. Also adds explicit
error handling when organization is null in promptsCheck().

Follow-up to #104990.
jaydgoss added a commit that referenced this pull request Jan 21, 2026
…106413)

Removes the redundant `organization_id` query parameter from the
frontend prompts API calls. The GET endpoint now uses the organization
from the URL path (after the fix in #104990), making this parameter
ignored but harmless.

Changes:
- Remove `organization_id` from `promptsCheck()`,
`makePromptsCheckQueryKey()`, and `batchedPromptsCheck()`
- Add explicit error handling in `promptsCheck()` when organization is
null (previously would create an invalid URL
`/organizations/undefined/...`)

Follow-up to #104990.

---------

Co-authored-by: Jay Goss <jaygoss@gmail.com>
@github-actions github-actions bot locked and limited conversation to collaborators Jan 31, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants