Skip to content

fix(releases): Add authorization check for project_id in release details endpoint#112879

Draft
semgrep-code-getsentry[bot] wants to merge 1 commit intomasterfrom
semgrep-autofix/1776121989
Draft

fix(releases): Add authorization check for project_id in release details endpoint#112879
semgrep-code-getsentry[bot] wants to merge 1 commit intomasterfrom
semgrep-autofix/1776121989

Conversation

@semgrep-code-getsentry
Copy link
Copy Markdown

Fix IDOR vulnerability where user-supplied project_id was used without verifying authorization.

Changes

  • Replace direct Project.objects.get_from_cache() call with self.get_projects() which performs proper permission checks
  • Validate that the user has access to the project and that it belongs to the organization before using it
  • Update all downstream usages to use the validated project object instead of the raw user input
  • Remove unused Project model import

Why

The project_id query parameter was taken directly from user input and used to fetch project data without verifying that the requesting user has access to that project or that it belongs to the organization. This allowed potential unauthorized access to release health data and session time bounds for projects the user should not have access to.

Using self.get_projects() ensures proper authorization checks are performed, following Sentry's security guidelines for handling user-supplied project IDs.

Semgrep Finding Details

The project_id query parameter (line 337) is taken directly from user input and used to fetch a Project via Project.objects.get_from_cache(id=int(project_id)) at line 361 without verifying the requesting user has access to that project or that it belongs to the organization. This project_id is then used to set release._for_project_id (affecting health data serialization) and passed directly to get_release_sessions_time_bounds at line 372, bypassing any project-level authorization.

Semgrep Assistant generated this pull request to fix a finding.


⚠️ Review carefully before merging. This PR was generated by AI and may cause breaking changes or introduce new vulnerabilities.

…ils endpoint

Fix IDOR vulnerability where user-supplied project_id was used without verifying authorization.

## Changes
- Replace direct `Project.objects.get_from_cache()` call with `self.get_projects()` which performs proper permission checks
- Validate that the user has access to the project and that it belongs to the organization before using it
- Update all downstream usages to use the validated project object instead of the raw user input
- Remove unused `Project` model import

## Why
The `project_id` query parameter was taken directly from user input and used to fetch project data without verifying that the requesting user has access to that project or that it belongs to the organization. This allowed potential unauthorized access to release health data and session time bounds for projects the user should not have access to.

Using `self.get_projects()` ensures proper authorization checks are performed, following Sentry's security guidelines for handling user-supplied project IDs.

## Semgrep Finding Details
The `project_id` query parameter (line 337) is taken directly from user input and used to fetch a Project via `Project.objects.get_from_cache(id=int(project_id))` at line 361 without verifying the requesting user has access to that project or that it belongs to the organization. This project_id is then used to set `release._for_project_id` (affecting health data serialization) and passed directly to `get_release_sessions_time_bounds` at line 372, bypassing any project-level authorization.

Semgrep Assistant generated this pull request to fix [a finding](https://semgrep.dev/orgs/sentry/ai-findings/750426332).
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 13, 2026
projects = self.get_projects(
request=request,
organization=organization,
project_ids=[int(project_id)],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Passing list instead of set to get_projects causes all project lookups to fail

The code passes project_ids=[int(project_id)] (a list) to get_projects() which expects set[int] | None. In _validate_fetched_projects(), the comparison ids != {p.id for p in filtered_projects} evaluates to True even when the project is found because [1] != {1} in Python. This causes PermissionDenied to be raised for all valid project lookups.

Verification

Read src/sentry/api/bases/organization.py lines 344-356 showing _validate_fetched_projects compares ids != {p.id for p in filtered_projects}. When ids is a list like [1] and the set is {1}, Python evaluates [1] != {1} as True because list and set types are never equal. Also verified line 565-566 shows proper pattern: converting list to set before calling get_projects.

Identified by Warden sentry-backend-bugs · M8M-VFV

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants