-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add vulnerability detection module for CVE-2026-33017 (Langflow unauthenticated RCE) #1653
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
8801f2e
c9e3b0c
15b9c59
7a6c8f5
f68a6cd
d655cf5
e78e7bd
d7eea7a
7ac0916
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,181 @@ | ||
| info: | ||
| name: langflow_cve_2026_33017_vuln | ||
| author: NSK-394 | ||
| severity: 9.8 | ||
| description: > | ||
| CVE-2026-33017 (CVSS 9.8) is an unauthenticated RCE in Langflow <= 1.8.2 | ||
| via the /api/v1/build_public_tmp/{{flow_id}}/flow endpoint, which processes | ||
| attacker-controlled flow node definitions instead of using only the stored | ||
| flow data. The official fix in 1.9.0 removes this behavior entirely, ignoring | ||
| attacker-supplied node data and building only the stored (empty) flow. | ||
| This module detects the vulnerable input-validation flaw by submitting a | ||
| uniquely-identified CustomComponent node and checking whether the server's | ||
| build-event stream references it. Testing against 1.8.2 (vulnerable) and | ||
| 1.9.0 (patched) shows: vulnerable instances process and reference the | ||
| injected node (visible as processing errors); patched instances discard | ||
| it before processing (empty vertex list in events). This confirms the | ||
| vulnerability's root cause (improper input handling); it does not | ||
| independently verify code execution. Non-destructive detection suitable | ||
| for production scanning. | ||
| reference: | ||
| - https://nvd.nist.gov/vuln/detail/CVE-2026-33017 | ||
| - https://github.com/langflow-ai/langflow/security/advisories/GHSA-vwmf-pq79-vjvx | ||
| profiles: | ||
| - vuln | ||
| - http | ||
| - critical_severity | ||
| - cve | ||
| - cve2026 | ||
| - langflow | ||
| - rce | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @NSK-394 |
||
| payloads: | ||
| - library: http | ||
| steps: | ||
| # Step 1: Obtain unauthenticated access token via AUTO_LOGIN (default enabled) | ||
| # Uses capturing group to extract actual token value from response | ||
| - method: get | ||
| timeout: 5 | ||
| headers: | ||
| User-Agent: Nettacker | ||
| ssl: false | ||
| url: | ||
| nettacker_fuzzer: | ||
| input_format: "{{schema}}://{target}:{{ports}}/api/v1/auto_login" | ||
| response: | ||
| save_to_temp_events_only: token | ||
| condition_type: and | ||
| conditions: | ||
| status_code: | ||
| regex: "200" | ||
| reverse: false | ||
| content: | ||
| # Capturing group: extract actual token string from "access_token":"<value>" | ||
| regex: '"access_token":"([^"]*)"' | ||
| reverse: false | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| # Step 2: Create a public flow (required to obtain flow_id for build endpoint) | ||
| # Uses capturing group to extract actual flow UUID | ||
| - method: post | ||
| timeout: 5 | ||
| headers: | ||
| User-Agent: Nettacker | ||
| Content-Type: application/json | ||
| Authorization: "Bearer dependent_on_temp_event[0]['content'][0]" | ||
| ssl: false | ||
| json: | ||
| name: nettacker_check | ||
| data: | ||
| nodes: [] | ||
| edges: [] | ||
| access_type: PUBLIC | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Whenever authentication and flow creation succeed, this request persists a Useful? React with 👍 / 👎. |
||
| url: | ||
| nettacker_fuzzer: | ||
| input_format: "{{schema}}://{target}:{{ports}}/api/v1/flows/" | ||
| response: | ||
| dependent_on_temp_event: token | ||
| save_to_temp_events_only: flow_id | ||
| condition_type: and | ||
| conditions: | ||
| status_code: | ||
| regex: "20[01]" | ||
| reverse: false | ||
| content: | ||
| # Capturing group: extract actual flow UUID from "id":"<uuid>" | ||
| regex: '"id":"([a-f0-9\-]{36})"' | ||
| reverse: false | ||
|
|
||
| # Step 3: Submit attacker-controlled flow data to build_public_tmp | ||
| # On vulnerable versions, this node data is accepted and processed. | ||
| # On patched versions, it is silently discarded before graph construction. | ||
| # Uses capturing group to extract actual job UUID | ||
| - method: post | ||
| timeout: 10 | ||
| headers: | ||
| User-Agent: Nettacker | ||
| Content-Type: application/json | ||
| Authorization: "Bearer dependent_on_temp_event[0]['content'][0]" | ||
| Cookie: "client_id=nettacker" | ||
| ssl: false | ||
| json: | ||
| data: | ||
| nodes: | ||
| - id: nettacker_vuln_check | ||
| type: genericNode | ||
| position: | ||
| x: 0 | ||
| y: 0 | ||
| data: | ||
| type: CustomComponent | ||
| id: nettacker_vuln_check | ||
| node: | ||
| template: | ||
| _type: CustomComponent | ||
| code: | ||
| value: "pass" | ||
| type: code | ||
| edges: [] | ||
| url: | ||
| nettacker_fuzzer: | ||
| input_format: "{{schema}}://{target}:{{ports}}/api/v1/build_public_tmp/dependent_on_temp_event[1]['content'][0]/flow" | ||
| response: | ||
| save_to_temp_events_only: job_id | ||
| dependent_on_temp_event: "token,flow_id" | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| condition_type: and | ||
| conditions: | ||
| status_code: | ||
| regex: "200" | ||
| reverse: false | ||
| content: | ||
| # Capturing group: extract actual job UUID from "job_id":"<uuid>" | ||
| regex: '"job_id":"([a-f0-9\-]{36})"' | ||
| reverse: false | ||
|
|
||
| # Step 4: Poll build-event stream to detect vulnerable behavior | ||
| # Vulnerable (1.8.2): server processes our injected node, error mentions our node id | ||
| # Patched (1.9.0): server discards our node, builds only empty flow (empty vertices list) | ||
| # Detection signal: presence of our distinctive node id in any event (error or otherwise) | ||
| # vs. absence/empty vertices list (patched). This confirms the endpoint processes | ||
| # attacker-supplied node data on vulnerable versions only. | ||
| - method: get | ||
| timeout: 15 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to the CVE only 2 seconds timeout should be sufficient ? (GHSA-vwmf-pq79-vjvx) |
||
| headers: | ||
| User-Agent: Nettacker | ||
| Authorization: "Bearer dependent_on_temp_event[0]['content'][0]" | ||
| ssl: false | ||
| url: | ||
| nettacker_fuzzer: | ||
| input_format: "{{schema}}://{target}:{{ports}}/api/v1/build/dependent_on_temp_event[2]['content'][0]/events" | ||
| response: | ||
| dependent_on_temp_event: "token,flow_id,job_id" | ||
| condition_type: and | ||
| conditions: | ||
| status_code: | ||
| regex: "200" | ||
| reverse: false | ||
| content: | ||
| # Match detection: our injected node id appears anywhere in event stream | ||
| # (vulnerable versions reference it during processing; patched versions ignore it) | ||
| regex: nettacker_vuln_check | ||
| reverse: false | ||
|
|
||
| # Step 5: Cleanup - Delete the created flow to avoid accumulating test artifacts | ||
| - method: delete | ||
| timeout: 5 | ||
| headers: | ||
| User-Agent: Nettacker | ||
| Authorization: "Bearer dependent_on_temp_event[0]['content'][0]" | ||
| ssl: false | ||
| url: | ||
| nettacker_fuzzer: | ||
| input_format: "{{schema}}://{target}:{{ports}}/api/v1/flows/dependent_on_temp_event[1]['content'][0]" | ||
| response: | ||
| dependent_on_temp_event: "token,flow_id" | ||
| condition_type: or | ||
| conditions: | ||
| status_code: | ||
| regex: "20[0-4]" | ||
| reverse: false | ||
| content: | ||
| regex: "deleted|Deleted|success" | ||
| reverse: true | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also please add: https://www.cisa.gov/news-events/alerts/2026/03/25/cisa-adds-one-known-exploited-vulnerability-catalog