← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2025-34291 · CWE-346 · Disclosed 2025-12-05

Langflow versions up to and including 1

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a stolen valet ticket that lets the attacker come back later and drive off the whole garage

CVE-2025-34291 is a *chain*, not a single bug: Langflow's default CORS posture (LANGFLOW_CORS_ORIGINS=* with credentials allowed), a cross-site refresh-token cookie posture, and a refresh flow without meaningful CSRF resistance let an attacker-controlled website mint fresh tokens for a victim's existing Langflow session. Those tokens can then be used against authenticated endpoints, including Langflow's code-validation path, turning a browser-origin bug into full server-side code execution. Authoritative metadata from NVD/GHSA says affected versions are Langflow up to and including 1.6.9.

The vendor's HIGH 8.8 is directionally right, but the v3 vector hides the real shape of the attack. This is *not* a clean unauthenticated socket-level RCE you can spray across the internet; it needs a reachable Langflow instance, unsafe CORS/cookie behavior, and a logged-in victim browser. That friction pushes it down from CRITICAL in real enterprise operations, but KEV status, observed exploitation, and Langflow's habit of storing high-value API keys drag it right back to the top of the HIGH bucket.

"Real RCE, but not wormable: the logged-in victim browser requirement keeps this out of CRITICAL."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a reachable Langflow and a live user session

The attacker first identifies a Langflow deployment that a victim browser can reach, usually an internet-exposed instance or one reachable from a corporate user network. They then lure a user who already has a valid Langflow session into opening an attacker-controlled page; CrowdSec notes this attack style naturally makes victim IPs show up in telemetry because the browser is doing the work.
Conditions required:
  • Langflow is reachable from the victim browser
  • A user has an active Langflow session or refresh cookie
  • The attacker can get that user to load attacker-controlled web content
Where this breaks in practice:
  • No direct exploit if nobody is logged in
  • Many enterprises do not expose Langflow broadly
  • Phishing, watering-hole, or ad-path delivery is still required
Detection/coverage: External scanners can find exposed Langflow product surfaces; this step is mostly detected through exposure management and user/web telemetry, not host signatures.
STEP 02

Abuse credentialed CORS to steal fresh tokens

The malicious page uses the browser to send cross-origin requests to Langflow's refresh path with credentials attached. Because the default posture allows wildcard origins with credentials and the refresh cookie is cross-site usable, the attacker can obtain fresh access/refresh tokens for the victim session without stealing a password.
Conditions required:
  • LANGFLOW_CORS_ALLOW_CREDENTIALS=True
  • CORS origins are wildcard or otherwise too broad
  • Refresh cookie/session settings permit cross-site delivery
  • Refresh endpoint lacks an effective CSRF barrier
Where this breaks in practice:
  • Any explicit origin allowlist breaks the easy path
  • SameSite=Lax or Strict materially reduces exploitability
  • Reverse proxies that normalize or block hostile Origin headers can help
Detection/coverage: DAST and config review can catch the risky CORS posture; ProjectDiscovery has a Nuclei template for this CVE, but scanner success does not prove a live exploitable user session.
STEP 03

Replay the token against authenticated code-execution features

With a valid token, the attacker stops being cross-origin constrained and simply talks to Langflow as the victim. Langflow documents authenticated endpoints such as POST /api/v1/validate/code; once the attacker holds the victim's token or API-equivalent session, they can reach the same authenticated surfaces the user can.
Conditions required:
  • Stolen token remains valid
  • Victim account can reach authenticated backend endpoints
  • Langflow instance exposes the relevant API paths
Where this breaks in practice:
  • Short token lifetimes reduce the window
  • Least-privileged users may have narrower workspace access
  • Backend-only or heavily proxied deployments can limit reachable surfaces
Detection/coverage: Look for anomalous refresh activity followed by unusual authenticated calls like /api/v1/validate/code, /build, or account/API-key operations from new IPs, ASNs, or user agents.
STEP 04

Execute code and harvest downstream secrets

The end state is server-side code execution in the Langflow environment plus access to whatever secrets, connectors, and flow data the workspace exposes. In practice that means API keys for model providers, databases, cloud services, and internal apps can be exfiltrated and reused for lateral movement well beyond the Langflow host itself.
Conditions required:
  • Langflow host/container can execute the submitted code path
  • Useful credentials or network reachability exist on the host/workspace
  • Outbound network access is available for payload retrieval or exfiltration
Where this breaks in practice:
  • Container isolation and seccomp can reduce host impact
  • Egress controls and metadata blocking slow post-exploitation
  • Secret scoping can limit downstream blast radius
Detection/coverage: EDR/runtime telemetry should catch suspicious child processes, curl/wget/python shell-outs, unexpected outbound traffic, and reads of env files, token stores, or cloud metadata endpoints.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusConfirmed active exploitation. CrowdSec says exploitation was observed starting 2026-01-23, and NVD now flags the CVE as being in CISA's KEV catalog.
KEV statusKEV-listed: YES. NVD records CISA adding it on 2026-05-21 with a federal due date of 2026-06-04.
Proof-of-concept / scanner availabilityPublic detection content exists. GitHub/OSV tracks the advisory as GHSA-577h-p2hh-v4mv, and ProjectDiscovery shipped a Nuclei template for CVE-2025-34291, lowering discovery and validation friction.
EPSSUser-supplied EPSS: 0.32059. That's elevated enough to take seriously even before KEV; third-party mirrors have shown it in roughly the mid-90th percentile range, but EPSS is daily and moves.
CVSS reality checkVendor v3: 8.8 HIGH (AV:N/AC:L/PR:L/UI:N/...) overstates how "direct" this is. The exploit described by NVD/Obsidian is closer to no prior auth but does require victim browser interaction, which is why the real-world score stays HIGH, not CRITICAL.
Affected versionsAuthoritative affected range: Langflow <= 1.6.9 in NVD and GHSA/OSV.
Fixed versionPatch signal is messy. CSA says Langflow addressed this in 1.9.3, while Obsidian's disclosure notes said 1.6.9 remained exploitable and that 1.7 would change defaults. Treat 1.9.3+ as the safe target, but note the public metadata is not perfectly aligned.
Exposure / scanning dataInternet exposure is real. In a prior Censys Langflow advisory, Censys observed 1,156 exposed Langflow servers online. That's product-level exposure data rather than CVE-specific measurement, but it tells you this is not a niche lab-only footprint.
Disclosure / researchDisclosed: 2025-12-05. Researcher disclosure and technical write-up came from Obsidian Security, with VulnCheck as the CVE source shown by NVD.
Threat-model nuanceThis is browser-mediated exploitation. CrowdSec notes observed source IPs skew residential because the victim's browser executes the attack, which makes classic perimeter correlation noisier than with direct RCE scanning.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (8.6/10)

The single biggest downward pressure is the logged-in victim browser requirement: this is not a point-and-shoot unauthenticated daemon exploit. The single biggest upward pressure is KEV-listed active exploitation against a secret-rich platform that can turn one stolen session into code execution plus credential theft across downstream SaaS and cloud systems.

HIGH Active exploitation and KEV status
MEDIUM Exact safe-version boundary in public metadata

Why this verdict

  • Downward pressure: requires a live user session and browser interaction — the attacker needs a victim already authenticated to Langflow and able to reach the instance, which narrows reach versus true unauthenticated RCE.
  • Downward pressure: exposed population is smaller than generic CVSS implies — only deployments with reachable Langflow plus unsafe CORS/cookie settings are in play, and many enterprises should already have these tools behind a proxy or dev network boundary.
  • Upward pressure: KEV plus real campaigns outweigh the friction — exploitation has been observed since 2026-01-23, CISA added it to KEV on 2026-05-21, and the post-exploitation blast radius is unusually high because Langflow stores reusable API keys and executes code by design.

Why not higher?

I am not calling this CRITICAL because the exploit chain is not a clean, unauthenticated network RCE. It depends on a victim browser, a valid session, and a reachable instance with unsafe defaults, which means reachability and reliability are materially lower than something like a one-request pre-auth service exploit.

Why not lower?

I am not dropping this to MEDIUM because the end state is still full code execution and likely secret theft, not a narrow account-only issue. KEV listing and observed exploitation remove the usual benefit of the doubt; attackers are already proving the chain works in real environments.

05 · Compensating Control

What to do — in priority order.

  1. Disable credentialed cross-origin requests — Set LANGFLOW_CORS_ALLOW_CREDENTIALS=False immediately where operationally possible. Because this CVE is KEV-listed/actively exploited, deploy this within hours; it severs the easiest token-theft leg of the chain while patching is organized.
  2. Replace wildcard origins with an explicit allowlist — Set LANGFLOW_CORS_ORIGINS to only the exact frontend origins that must talk to Langflow. Do this within hours for exposed instances; wildcard origins are the hinge that makes the browser side of the exploit cheap.
  3. Put Langflow behind a real access boundary — Move exposed instances behind a reverse proxy with authentication, network ACLs, or VPN/identity-aware proxy controls so arbitrary internet traffic cannot reach the app directly. For this KEV item, do it within hours for any internet-facing deployment that cannot be patched immediately.
  4. Rotate stored secrets after suspected exposure — If an instance was internet-reachable or handled untrusted user browsing since 2026-01-23, assume workspace secrets may be burned and rotate Langflow-held API keys, cloud tokens, and database credentials. Start within hours on exposed/high-value instances because patching does not un-leak already stolen tokens.
  5. Monitor and alert on refresh and code-validation abuse — Create detections for unusual /api/v1/refresh traffic, unexpected Origin headers, and follow-on calls to /api/v1/validate/code or build endpoints from new IPs/user agents. Stand this up within hours for exposed instances to catch replay and post-exploitation while remediation proceeds.
What doesn't work
  • MFA alone doesn't stop reuse of a stolen live session token once the browser has already authenticated.
  • A generic WAF rule set alone is weak here because the exploit uses legitimate browser behavior and authenticated API calls after token theft.
  • Only patching the frontend cookie code is insufficient if backend cookie/CORS behavior remains permissive; the chain is a configuration and request-validation problem, not just a UI bug.
  • Relying on EDR alone is too late; it may catch the payload stage, but it does not prevent session hijack or token theft.
06 · Verification

Crowdsourced verification payload.

Run this on the Langflow host or inside the Langflow container. Invoke it as bash verify_cve_2025_34291.sh /path/to/.env (example: docker exec langflow bash /tmp/verify_cve_2025_34291.sh /app/.env). It needs only local read access to the installed langflow package metadata and, if provided, the Langflow .env file; root is not required unless app files are restricted.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# verify_cve_2025_34291.sh
# Detect likely exposure state for CVE-2025-34291 on a Langflow host/container.
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 1=vulnerable, 0=patched, 2=unknown

set -u

ENV_FILE="${1:-}"
VERSION=""
CORS_ORIGINS=""
CORS_ALLOW_CREDENTIALS=""
STATUS="UNKNOWN"
REASON=""

trim() {
  local s="$1"
  s="${s#${s%%[![:space:]]*}}"
  s="${s%${s##*[![:space:]]}}"
  printf '%s' "$s"
}

norm_bool() {
  local v
  v="$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')"
  case "$v" in
    true|1|yes|y|on) printf 'true' ;;
    false|0|no|n|off) printf 'false' ;;
    *) printf '' ;;
  esac
}

verlte() {
  # returns 0 if $1 <= $2
  [ "$1" = "$2" ] && return 0
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]
}

vergte() {
  # returns 0 if $1 >= $2
  [ "$1" = "$2" ] && return 0
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ]
}

load_env_file() {
  local f="$1"
  [ -f "$f" ] || return 0
  while IFS='=' read -r k v; do
    k="$(trim "$k")"
    v="$(trim "$v")"
    [ -z "$k" ] && continue
    case "$k" in
      \#*) continue ;;
      export\ *) k="${k#export }" ;;
    esac
    v="${v%\r}"
    v="${v%\"}"
    v="${v#\"}"
    v="${v%\'}"
    v="${v#\'}"
    case "$k" in
      LANGFLOW_CORS_ORIGINS) CORS_ORIGINS="$v" ;;
      LANGFLOW_CORS_ALLOW_CREDENTIALS) CORS_ALLOW_CREDENTIALS="$v" ;;
    esac
  done < "$f"
}

get_version() {
  if command -v python3 >/dev/null 2>&1; then
    VERSION="$(python3 - <<'PY' 2>/dev/null
from importlib import metadata
try:
    print(metadata.version('langflow'))
except Exception:
    pass
PY
)"
  fi

  if [ -z "$VERSION" ] && command -v pip >/dev/null 2>&1; then
    VERSION="$(pip show langflow 2>/dev/null | awk -F': ' '/^Version: /{print $2; exit}')"
  fi

  if [ -z "$VERSION" ] && command -v pip3 >/dev/null 2>&1; then
    VERSION="$(pip3 show langflow 2>/dev/null | awk -F': ' '/^Version: /{print $2; exit}')"
  fi
}

# Prefer explicit env file if provided, otherwise fall back to current environment.
if [ -n "$ENV_FILE" ]; then
  load_env_file "$ENV_FILE"
fi

[ -z "$CORS_ORIGINS" ] && CORS_ORIGINS="${LANGFLOW_CORS_ORIGINS:-}"
[ -z "$CORS_ALLOW_CREDENTIALS" ] && CORS_ALLOW_CREDENTIALS="${LANGFLOW_CORS_ALLOW_CREDENTIALS:-}"

CORS_ALLOW_CREDENTIALS="$(norm_bool "$CORS_ALLOW_CREDENTIALS")"
get_version

RISKY_CORS="false"
if [ "${CORS_ORIGINS}" = "*" ] && [ "${CORS_ALLOW_CREDENTIALS}" = "true" ]; then
  RISKY_CORS="true"
fi

if [ -n "$VERSION" ]; then
  if verlte "$VERSION" "1.6.9"; then
    STATUS="VULNERABLE"
    REASON="Installed langflow version $VERSION is within authoritative affected range (<= 1.6.9)."
  elif vergte "$VERSION" "1.9.3"; then
    STATUS="PATCHED"
    REASON="Installed langflow version $VERSION is at or above the documented security target 1.9.3."
    if [ "$RISKY_CORS" = "true" ]; then
      REASON="$REASON Warning: CORS is still configured as wildcard + credentials, which is dangerous even if this CVE is patched."
    fi
  else
    STATUS="UNKNOWN"
    REASON="Installed langflow version $VERSION is newer than 1.6.9 but below 1.9.3; public advisories are inconsistent on the exact fixed boundary."
    if [ "$RISKY_CORS" = "true" ]; then
      REASON="$REASON Risky CORS configuration is also present."
    fi
  fi
else
  STATUS="UNKNOWN"
  REASON="Could not determine installed langflow version from python package metadata."
  if [ "$RISKY_CORS" = "true" ]; then
    REASON="$REASON Risky CORS configuration (wildcard origins + credentials) is present."
  fi
fi

printf '%s\n' "$STATUS"
printf '%s\n' "$REASON"

case "$STATUS" in
  PATCHED) exit 0 ;;
  VULNERABLE) exit 1 ;;
  *) exit 2 ;;
esac
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, treat every reachable Langflow <=1.6.9 as an active incident candidate, not just another backlog CVE. Because this is KEV-listed and actively exploited, the noisgate mitigation SLA is patch / mitigate immediately, within hours: kill wildcard credentialed CORS, put exposed instances behind a real access boundary, and start rotating stored integration secrets on any internet-reachable deployment. Your noisgate remediation SLA for this HIGH verdict is <= 180 days, but that is an outer compliance bound, not an operational target; if you own exposed Langflow, move the upgrade to the front of the queue now.

Sources

  1. NVD CVE-2025-34291
  2. GitHub Advisory GHSA-577h-p2hh-v4mv
  3. Obsidian Security technical write-up
  4. CrowdSec exploitation report
  5. Cloud Security Alliance research note
  6. Langflow authentication and CORS documentation
  7. Langflow validate-code endpoint documentation
  8. Censys Langflow exposure advisory
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.