{
  "variant_id": "CVE-2026-55255-variant-v2-workflows",
  "created_at": "2026-07-07T21:50:08Z",
  "variant_summary": "Alternate trigger of CVE-2026-55255: the same IDOR in get_flow_by_id_or_endpoint_name is reachable via POST /api/v2/workflows (Developer API). execute_workflow calls get_flow_by_id_or_endpoint_name(workflow_request.flow_id, api_key_user.id) then executes the resolved flow with no check_flow_user_permission; the vulnerable UUID branch ignores api_key_user.id, so an authenticated attacker runs a victim's flow by UUID and reads the output. Same root cause, same trust boundary, different endpoint + request shape. Closed by the released fix b0afe3d2d6 (PR #12832) which enforces flow.user_id != uuid_user_id -> None on the UUID branch; same request returns 404 FLOW_NOT_FOUND on the fixed code. NOT a bypass.",
  "relation": "newer_version_sibling",
  "origin_kind": "pruva_variant",
  "repository": "github.com/langflow-ai/langflow",
  "submitted_target": {
    "target_kind": "commit",
    "commit_sha": "f52d0f0072dcb6968f147ba3a90a3c1ece79995b",
    "version": "langflow 1.9.0 / langflow-base 0.9.0",
    "ref": "f52d0f0072",
    "display": "langflow 1.9.0 (commit f52d0f0072) — vulnerable parent of the fix"
  },
  "variant_target": {
    "target_kind": "commit",
    "commit_sha": "f52d0f0072dcb6968f147ba3a90a3c1ece79995b",
    "version": "langflow 1.9.0 / langflow-base 0.9.0",
    "ref": "f52d0f0072",
    "display": "langflow 1.9.0 (commit f52d0f0072) — variant reproduced on vulnerable build; also tested fixed build b0afe3d2d6 where it is blocked (404 FLOW_NOT_FOUND)"
  },
  "same_root_cause_confidence": "high",
  "same_surface_confidence": "high",
  "claimed_surface": "api_remote",
  "validated_surface": "api_remote",
  "required_entrypoint_kind": "endpoint",
  "required_entrypoint_detail": "POST /api/v2/workflows with x-api-key header and JSON body {flow_id: victim_flow_uuid, inputs: {ChatInput-<id>.input_value: <probe>}} against a running Langflow server with LANGFLOW_DEVELOPER_API_ENABLED=true",
  "attacker_controlled_input": "victim flow UUID supplied as the `flow_id` field in POST /api/v2/workflows (Developer API) with the attacker's own x-api-key; optional flat `inputs` inject an attacker-chosen probe into the victim flow's ChatInput, which is reflected in the executed flow's ChatOutput",
  "trigger_path": "POST /api/v2/workflows -> api.v2.workflow.execute_workflow -> get_flow_by_id_or_endpoint_name(workflow_request.flow_id, api_key_user.id) -> vulnerable UUID branch: session.get(Flow, flow_id) ignores user_id -> execute_sync_workflow builds graph with user_id=attacker.id and runs the VICTIM flow -> returns WorkflowExecutionResponse with status=completed and the victim flow's outputs",
  "observed_impact_class": "authz_bypass",
  "exploitability_confidence": "high",
  "evidence_scope": "production_path",
  "runtime_manifest_present": true,
  "end_to_end_target_reached": true,
  "inferred": false,
  "is_bypass": false,
  "variant_kind": "alternate_trigger",
  "variant_reproduced_on_vulnerable": true,
  "variant_blocked_on_fixed": true,
  "fix_commit_sha": "b0afe3d2d6506f3d69aff83325d46f0ec481e02a",
  "fix_pr": "#12832",
  "fix_summary": "helpers/flow.py normalizes user_id once and enforces flow.user_id != uuid_user_id -> None on the UUID branch (and scopes the endpoint_name branch when user_id is set); cross-user lookups return None -> shared 404. Also swaps the three /run* routes to auth-aware wrappers get_flow_for_api_key_user / get_flow_for_current_user.",
  "claim_block_reason": null,
  "blocking_mitigation": "fixed flow.py (commit b0afe3d2d6) adds flow.user_id != uuid_user_id -> None ownership check on the UUID branch; the same POST /api/v2/workflows request returns HTTP 404 {detail:{code:FLOW_NOT_FOUND,...}} on the fixed code",
  "file_path": "src/backend/base/langflow/api/v2/workflow.py",
  "line_start": 151,
  "line_end": 151,
  "secondary_anchors": [
    {
      "file_path": "src/backend/base/langflow/helpers/flow.py",
      "line_start": 404,
      "line_end": 406
    },
    {
      "file_path": "src/backend/base/langflow/api/v1/openai_responses.py",
      "line_start": 635,
      "line_end": 635
    }
  ],
  "review_scope_paths": [
    "src/backend/base/langflow/helpers/flow.py",
    "src/backend/base/langflow/api/v2/workflow.py",
    "src/backend/base/langflow/api/v1/openai_responses.py",
    "src/backend/base/langflow/api/v1/endpoints.py",
    "src/backend/base/langflow/agentic/mcp/server.py"
  ],
  "artifact_refs": {
    "variant_manifest": "bundle/vuln_variant/variant_manifest.json",
    "validation_verdict": "bundle/vuln_variant/validation_verdict.json",
    "runtime_manifest": "bundle/vuln_variant/runtime_manifest.json",
    "repro_log": "bundle/logs/vuln_variant/reproduction_steps.log",
    "root_cause_equivalence": "bundle/vuln_variant/root_cause_equivalence.json",
    "reproducer": [
      "bundle/vuln_variant/reproduction_steps.sh",
      "bundle/vuln_variant/artifacts/variant_response_vuln.json",
      "bundle/vuln_variant/artifacts/variant_response_fixed.json",
      "bundle/vuln_variant/artifacts/summary.json"
    ]
  }
}
