Skip to content

fix: add missing ownership checks in projects API (GHSA-rpf3-3973-4gjr)#12462

Merged
carlosrcoelho merged 9 commits into
release-1.9.0from
fix/project-flow-ownership-check
Apr 8, 2026
Merged

fix: add missing ownership checks in projects API (GHSA-rpf3-3973-4gjr)#12462
carlosrcoelho merged 9 commits into
release-1.9.0from
fix/project-flow-ownership-check

Conversation

@andifilhohub
Copy link
Copy Markdown
Member

@andifilhohub andifilhohub commented Apr 2, 2026

Summary

Fixes GHSA-rpf3-3973-4gjr — authenticated users could reassign flows they don't own into their project, exfiltrate the flow data via paginated API, and cause the victim to lose access to their flow.

Root cause — two missing ownership checks in projects.py:

  • POST /api/v1/projects/: flows_list and components_list were applied via UPDATE without verifying Flow.user_id == current_user.id, allowing any user to move another user's flow into their own project
  • GET /api/v1/projects/{id}?page=&size=: the paginated code path fetched flows with no user_id filter, leaking flows belonging to other users

Fix: add Flow.user_id == current_user.id to both UPDATE statements in create_project and to the paginated SELECT in read_project.

Attack chain

  1. Attacker creates a project with flows_list: [victim_flow_id]
  2. Victim's flow is silently moved to attacker's project — victim loses access
  3. Attacker calls GET /api/v1/projects/{attacker_project_id}?page=1&size=50 and receives the victim's full flow data

Test plan

  • Victim creates a flow
  • Attacker creates a project with flows_list: [victim_flow_id] → project must be created empty
  • Victim's flow folder_id must remain unchanged
  • GET /api/v1/projects/{attacker_project_id}?page=1&size=50 must return 0 flows

… read (GHSA-rpf3-3973-4gjr)

Prevent authenticated users from reassigning flows they don't own by adding
`Flow.user_id == current_user.id` to the UPDATE statements in `create_project`.
Also fix the paginated path in `read_project` which was missing the same filter,
allowing cross-user flow exfiltration via the `?page=&size=` query parameters.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 2, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6daf5059-b9ae-4b55-b387-5981c90a7c78

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/project-flow-ownership-check

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added the bug Something isn't working label Apr 2, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 2, 2026

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 52.01%. Comparing base (cde9f23) to head (4c9b83a).
⚠️ Report is 1 commits behind head on release-1.9.0.

Files with missing lines Patch % Lines
src/backend/base/langflow/api/v1/projects.py 0.00% 1 Missing ⚠️

❌ Your patch status has failed because the patch coverage (0.00%) is below the target coverage (40.00%). You can increase the patch coverage or adjust the target coverage.
❌ Your project status has failed because the head coverage (49.28%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                @@
##           release-1.9.0   #12462      +/-   ##
=================================================
+ Coverage          51.83%   52.01%   +0.17%     
=================================================
  Files               2007     2004       -3     
  Lines             181207   181815     +608     
  Branches           27099    28337    +1238     
=================================================
+ Hits               93931    94572     +641     
+ Misses             86226    86193      -33     
  Partials            1050     1050              
Flag Coverage Δ
backend 55.68% <0.00%> (+0.02%) ⬆️
frontend 51.82% <ø> (+0.25%) ⬆️
lfx 49.28% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/backend/base/langflow/api/v1/projects.py 37.75% <0.00%> (ø)

... and 104 files with indirect coverage changes

🚀 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.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 2, 2026

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 33%
33.5% (37901/113131) 66.75% (5072/7598) 34.79% (891/2561)

Unit Test Results

Tests Skipped Failures Errors Time
3688 0 💤 0 ❌ 0 🔥 7m 38s ⏱️

Copy link
Copy Markdown
Member

@Cristhianzl Cristhianzl left a comment

Choose a reason for hiding this comment

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

Please add test in your PR.

TESTING

Coverage Requirements

  • No tests included in this PR

This is a CRITICAL gap for a security fix. The PR description includes a test plan but no automated tests.

Required tests:

  1. Test: attacker cannot steal victim's flow via create_project

    • User A creates a flow
    • User B creates a project with flows_list: [user_a_flow_id]
    • Assert: User A's flow folder_id is unchanged
    • Assert: User B's project contains 0 flows
  2. Test: paginated read_project does not leak other users' flows

    • Setup: project with flows from two different users
    • Assert: GET /projects/{id}?page=1&size=50 returns only current user's flows
  3. Test: attacker cannot steal victim's flow via update_project (for the finding above)

  4. Test: download_file does not include other users' flows (for the finding above)

Result: FAIL — security fixes MUST have regression tests.

@ogabrielluiz ogabrielluiz changed the title fix: enforce ownership check on flow assignment and paginated project… fix: add missing ownership checks in projects API (GHSA-rpf3-3973-4gjr) Apr 7, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 7, 2026
- test_create_project_cannot_steal_other_users_flow: asserts that
  flows_list in create_project does not move flows owned by another user
- test_read_project_paginated_does_not_leak_other_users_flows: asserts
  that paginated GET /projects/{id} only returns flows owned by the
  requesting user
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 7, 2026
…ecks

Remove advisory IDs from test names and docstrings, rename helper and
test functions to match the existing codebase conventions.
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 7, 2026
@andifilhohub andifilhohub requested a review from Cristhianzl April 7, 2026 17:13
Copy link
Copy Markdown
Member

@Cristhianzl Cristhianzl left a comment

Choose a reason for hiding this comment

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

lgtm

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 7, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 7, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 7, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 7, 2026
@carlosrcoelho carlosrcoelho enabled auto-merge April 7, 2026 20:36
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 7, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 8, 2026
@carlosrcoelho carlosrcoelho added this pull request to the merge queue Apr 8, 2026
Merged via the queue into release-1.9.0 with commit 5ea4cfc Apr 8, 2026
105 of 107 checks passed
@carlosrcoelho carlosrcoelho deleted the fix/project-flow-ownership-check branch April 8, 2026 13:31
Adam-Aghili pushed a commit that referenced this pull request Apr 15, 2026
…r) (#12462)

* fix: enforce ownership check on flow assignment and paginated project read (GHSA-rpf3-3973-4gjr)

Prevent authenticated users from reassigning flows they don't own by adding
`Flow.user_id == current_user.id` to the UPDATE statements in `create_project`.
Also fix the paginated path in `read_project` which was missing the same filter,
allowing cross-user flow exfiltration via the `?page=&size=` query parameters.

* test: add security regression tests for GHSA-rpf3-3973-4gjr

- test_create_project_cannot_steal_other_users_flow: asserts that
  flows_list in create_project does not move flows owned by another user
- test_read_project_paginated_does_not_leak_other_users_flows: asserts
  that paginated GET /projects/{id} only returns flows owned by the
  requesting user

* test: improve security test naming and style for project ownership checks

Remove advisory IDs from test names and docstrings, rename helper and
test functions to match the existing codebase conventions.

* [autofix.ci] apply automated fixes

* fix: address ruff linting errors in ownership security tests

* test: add coverage for legitimate flows_list and paginated read assignments

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Carlos Coelho <80289056+carlosrcoelho@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants