Skip to content

fix(API): Nested viewsets expose data across projects and organisations#7945

Open
khvn26 wants to merge 4 commits into
mainfrom
fix/nested-viewset-cross-scope-idor
Open

fix(API): Nested viewsets expose data across projects and organisations#7945
khvn26 wants to merge 4 commits into
mainfrom
fix/nested-viewset-cross-scope-idor

Conversation

@khvn26

@khvn26 khvn26 commented Jul 6, 2026

Copy link
Copy Markdown
Member

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

In this PR, we fix four vulnerabilites:

  1. MultivariateFeatureOptionViewSet resolved the feature by bare feature_pk, so a user could read another project's multivariate options. Scoped the lookup to the URL's project, mirroring create.
  2. FeatureExternalResourceViewSet filtered the list by bare feature_pk, and FeaturePermissions applied no project check on list. Scoped the lookup to the caller's permitted projects, matching FeatureViewSet.
  3. UserPermissionGroupEnvironmentPermissionsViewSet gated only by IsAuthenticated, unlike its sibling UserEnvironmentPermissionsViewSet. Because the environment client-side api key is not a secret, any authenticated user could read and delete another organisation's environment group permission assignments. Added the missing NestedEnvironmentPermissions.
  4. GithubRepositoryViewSet filtered by bare github_pk while the permission only checked membership of the URL's organisation_pk, neither tying the configuration to that organisation. Validated the configuration belongs to the organisation in HasPermissionToGithubConfiguration, covering every action.

How did you test this code?

Added regression tests.

khvn26 added 4 commits July 6, 2026 11:23
`MultivariateFeatureOptionViewSet.get_queryset` resolved the feature by
bare `feature_pk`, ignoring `project_pk`. The list action runs no
object-level permission check, so any user with a project could read
another project's multivariate options by enumerating feature ids.

Scope the feature lookup to the URL's project, mirroring `create`.

beep boop
…ojects on list

`FeatureExternalResourceViewSet.get_queryset` filtered the list by bare
`feature_pk`, and `FeaturePermissions` applies no project check on the
list action ("handled by the view"). So any authenticated user could
read another feature's linked issue/PR resources by enumerating feature
ids.

Scope the feature lookup to the caller's permitted projects, matching
the pattern used by `FeatureViewSet`.

beep boop
… any authenticated user

`UserPermissionGroupEnvironmentPermissionsViewSet` was gated only by
`IsAuthenticated`, unlike its sibling `UserEnvironmentPermissionsViewSet`
which also uses `NestedEnvironmentPermissions`. Since the environment
client-side api key is not a secret, any authenticated user could read,
and delete, another organisation's environment group permission
assignments regardless of membership.

Add `NestedEnvironmentPermissions` so the caller must hold the relevant
permission on the environment.

beep boop
`GithubRepositoryViewSet.get_queryset` filtered by bare `github_pk`, and
`HasPermissionToGithubConfiguration` only checked membership of the URL's
`organisation_pk`. Neither tied the GitHub configuration to that
organisation, so a member of one organisation could read (and, via the
create path, write) repositories under another organisation's
configuration.

Validate that the configuration in the URL belongs to the organisation
in `HasPermissionToGithubConfiguration`, covering every action. A
non-numeric `github_pk` is left for the view to reject with a 400.

beep boop
@khvn26 khvn26 requested a review from a team as a code owner July 6, 2026 11:05
@khvn26 khvn26 requested review from emyller and removed request for a team July 6, 2026 11:05
@cursor

cursor Bot commented Jul 6, 2026

Copy link
Copy Markdown

Bugbot is not enabled for this team, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Jul 6, 2026 11:05am
flagsmith-frontend-preview Ignored Ignored Jul 6, 2026 11:05am
flagsmith-frontend-staging Ignored Ignored Jul 6, 2026 11:05am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR tightens authorisation checks across several endpoints to prevent cross-organisation and cross-project data access. It adds NestedEnvironmentPermissions to the environment user-group permissions viewset, scopes feature external resource and multivariate feature option querysets to the correct project, and extends the GitHub configuration permission to verify configuration ownership by organisation. Corresponding unit tests were added to assert 403/404 responses for these cross-tenant scenarios.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Changes

Cohort / File(s) Change Summary
api/environments/permissions/views.py Adds NestedEnvironmentPermissions to permission classes
api/features/feature_external_resources/views.py Scopes get_queryset to permitted projects via VIEW_PROJECT
api/features/multivariate/views.py Scopes Feature lookup by project_pk and feature_pk
api/integrations/github/permissions.py Adds organisation ownership check for github_pk
Test files (4) Adds unit tests for 403/404 cross-organisation/project scenarios

Sequence Diagram(s)

See per-layer diagrams in the hidden review stack artifact above.

Related issues: Not specified in the provided context.

Related PRs: Not specified in the provided context.

Suggested labels: security, bug, api

Suggested reviewers: Not specified in the provided context.

🐰 A hop through permissions, tight and true,
Cross-org peeks now get a "403 for you!"
Features scoped, resources checked with care,
GitHub configs guarded, ownership laid bare,
Tests confirm each fence is nicely drawn anew.


Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added api Issue related to the REST API fix labels Jul 6, 2026
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-e2e:pr-7945 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-api-test:pr-7945 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-frontend:pr-7945 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-api:pr-7945 Finished ✅ Results
ghcr.io/flagsmith/flagsmith:pr-7945 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-private-cloud:pr-7945 Finished ✅ Results

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.63%. Comparing base (8617611) to head (8c490e1).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7945   +/-   ##
=======================================
  Coverage   98.63%   98.63%           
=======================================
  Files        1497     1497           
  Lines       59189    59240   +51     
=======================================
+ Hits        58383    58434   +51     
  Misses        806      806           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 084d2baf-5008-457f-9618-316511df206d

📥 Commits

Reviewing files that changed from the base of the PR and between 8617611 and 8c490e1.

📒 Files selected for processing (8)
  • api/environments/permissions/views.py
  • api/features/feature_external_resources/views.py
  • api/features/multivariate/views.py
  • api/integrations/github/permissions.py
  • api/tests/unit/environments/permissions/test_unit_environments_views.py
  • api/tests/unit/features/multivariate/test_unit_multivariate_views.py
  • api/tests/unit/features/test_unit_feature_external_resources_views.py
  • api/tests/unit/integrations/github/test_unit_github_views.py

Comment thread api/integrations/github/permissions.py
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  6 passed

Details

stats  6 tests across 4 suites
duration  42.3 seconds
commit  8c490e1
info  🔄 Run: #18050 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  4 passed

Details

stats  4 tests across 3 suites
duration  45.6 seconds
commit  8c490e1
info  🔄 Run: #18050 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  5 passed

Details

stats  5 tests across 4 suites
duration  10.9 seconds
commit  8c490e1
info  🔄 Run: #18050 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  4 passed

Details

stats  4 tests across 3 suites
duration  42.7 seconds
commit  8c490e1
info  🔄 Run: #18050 (attempt 1)

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Visual Regression

19 screenshots compared. See report for details.
View full report

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

Labels

api Issue related to the REST API fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant