A bouncer who checks your VIP wristband color but never looks which club issued it
n8n's token-exchange identity resolution matches external identities to local n8n accounts using only the JWT sub claim while ignoring the iss (issuer) claim. When more than one trusted token-exchange issuer is configured, an attacker who holds a valid JWT from *any* trusted issuer where they can control or predict the sub value can authenticate as a victim user under a *different* trusted issuer that happens to share the same sub. Affected versions are all releases prior to 2.27.4 and the 2.28.0 line prior to 2.28.1. Single-issuer deployments — which is the default — are not exposed.
The vendor label of MEDIUM (6.8) is defensible and we agree with the bucket. This is a genuine authentication logic flaw (CWE-287 / CWE-346 origin validation error), but the exploitation preconditions are unusually restrictive: the operator must have deliberately configured multiple trusted issuers, the attacker must already hold credentials on one of them, and there must be a sub collision with a privileged user under a different issuer. That is a real risk in federated B2B automation tenancies, but it is not a spray-and-pray Internet bug.
5 steps from start to impact.
Enumerate n8n instance and confirm multi-issuer token exchange
/rest/settings, favicon hash) and confirms that token-exchange auth is enabled with ≥2 trusted issuers. Tools: curl, Shodan/Censys favicon queries, or referenced n8n footprint scanners.- Network reachability to the n8n API
- Target has multi-issuer token exchange configured
- Default n8n installs use username/password or single-issuer OIDC — multi-issuer is a deliberate advanced config
- Most enterprise n8n deployments are internal-only behind SSO gateway
Obtain a valid JWT from any trusted issuer
oauth2-cli or curl against the issuer's token endpoint.- An account on any of the trusted issuers
- Ability to influence the
subclaim (many IdPs allow subject aliasing or use email as sub)
- If all configured issuers are internal corporate IdPs, external attackers cannot get a starter token
- Enterprise IdPs typically use opaque immutable
subvalues (GUIDs) — collisions are effectively impossible without insider knowledge
Predict or brute the victim's sub under the other issuer
sub value. Where issuers use email-as-sub, this is trivial (sub: [email protected]). Where issuers use opaque IDs, attacker needs OSINT/leaks or an issuer that lets them pick sub.- Knowledge of an n8n user's
subunder an issuer distinct from the attacker's own
- Opaque GUID
subvalues across mismatched IdPs cannot be forged - Requires reconnaissance of victim tenant user list
iss vs. resolved user's provisioning source flags this.Exchange the token, land in the victim's session
sub alone, ignoring iss, and issue an n8n session bound to the victim. Weaponization is a single curl — no public exploit repo needed.- Endpoint reachable
- Vulnerable version <2.27.4 or 2.28.0
- Patched instances (2.27.4, 2.28.1) reject cross-issuer resolution
Abuse victim's workflows for credential theft / lateral movement
- Victim has stored credentials or elevated workflow rights
- RBAC on shared credentials in n8n Enterprise limits blast radius per user
- Egress filtering restricts new outbound destinations
The supporting signals.
| In-the-wild exploitation | None observed as of 2026-07-16. Not KEV-listed. No GreyNoise tag. |
|---|---|
| Public PoC | No public PoC repo. Exploit is trivial (curl + JWT with chosen sub) once preconditions are met. |
| EPSS | 0.00143 (~0.14%) — bottom quartile of exploit probability. |
| CVSS 3.1 vector | AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N — network, high complexity, low priv, no user interaction, high confidentiality+integrity impact, no availability impact. |
| CWE | CWE-287 Improper Authentication (secondary CWE-346 Origin Validation Error). |
| Affected versions | All n8n < 2.27.4; 2.28.0 through < 2.28.1. |
| Fixed versions | 2.27.4 and 2.28.1 (2026-07-09). |
| Exposure population (Shodan/Censys) | ~15–25k public n8n instances by favicon; unknown fraction with multi-issuer token exchange — realistically <1% of installs. |
| Disclosure | 2026-07-09 via GitHub Security Advisory on n8n-io/n8n. |
| Reporter | Coordinated disclosure via n8n GHSA program; researcher not publicly credited at time of writing. |
noisgate verdict.
The single decisive factor is a narrow precondition stack: the target must run n8n with *multiple* trusted token-exchange issuers, and the attacker must hold a valid JWT on one of them with a sub colliding with a victim under another — a config present in a small minority of installs. Blast radius on a hit is real (session takeover, workflow credential exposure), but the reachable population is too small to justify HIGH.
Why this verdict
- Precondition-heavy chain: attacker must (a) reach the API, (b) hold a JWT on a trusted issuer, and (c) know or forge a colliding
sub. Any one missing kills the chain. - Multi-issuer token exchange is not default: the vast majority of n8n deployments run single-issuer OIDC or username/password and are unaffected regardless of version.
- Role multiplier: n8n is a workflow/automation server — it commonly holds long-lived API credentials to cloud, DB, SaaS. On a compromise it can pivot broadly, so the ceiling is not benign, but n8n itself is not canonically an identity/hypervisor/CA role. Floor stays at MEDIUM.
- EPSS 0.00143 and no PoC — real-world exploit interest is minimal one week post-disclosure.
- Vendor patch is drop-in (
npm i [email protected]or2.28.1); no schema migration friction to slow rollout.
Why not higher?
HIGH would require either broad exposure of the vulnerable config or a public weaponized PoC with active scanning. Neither is present: multi-issuer token exchange is a minority configuration, EPSS sits at 0.14%, and there is no KEV listing or GreyNoise activity. Attack complexity is legitimately HIGH per the vendor vector.
Why not lower?
LOW would ignore that a successful chain yields full session takeover as an arbitrary user, with confidentiality and integrity both rated HIGH by the vendor. n8n instances routinely store production API keys in workflow credentials, so the post-exploit blast radius on a hit is not trivial — it warrants a real 30-to-180-day upgrade cycle, not backlog.
What to do — in priority order.
- Reduce to a single trusted token-exchange issuer — The vulnerability is only reachable when
>1issuers are trusted. AuditN8N_TOKEN_EXCHANGE_ISSUERS(or equivalent config) and collapse to one authoritative issuer. Deploy within the 30-day noisgate mitigation SLA for HIGH-adjacent MEDIUM — treat as ≤30 days if you cannot upgrade this week. - Restrict n8n API to internal networks and SSO-gated reverse proxy — Front n8n with a WAF/reverse proxy that enforces MFA-backed SSO before requests reach the token-exchange endpoint. This removes the anonymous reachability precondition even if multi-issuer stays configured.
- Rotate stored workflow credentials on affected instances — If you have run vulnerable versions with multi-issuer for any time, assume potential compromise: rotate every credential in every workflow, prioritizing cloud IAM keys and SMTP/API tokens. Do this within the 30-day window.
- Enable and forward n8n audit logs to SIEM — Hunt for token-exchange auth events where the resolved user's provisioning
issdiffers from the tokeniss. Any hit is either the bug or a legitimate misconfiguration — both worth resolving.
- Rotating admin passwords — the flaw is in JWT origin validation, not credential secrecy.
- IP allowlisting the n8n UI — the token-exchange endpoint is typically the same origin as legitimate SSO users, so allowlisting doesn't distinguish attacker JWTs from real ones.
- Enabling MFA in n8n — MFA is bypassed because the token exchange treats the JWT as already-authenticated proof of identity.
Crowdsourced verification payload.
Run on the n8n host (or against a container image) as a user who can read the n8n config and query the API. Example: ./check-cve-2026-59208.sh https://n8n.internal.tld. No root required if N8N_CONFIG_FILES and the running version are readable by the invoking user.
#!/usr/bin/env bash
# check-cve-2026-59208.sh — n8n cross-issuer JWT confusion check
# Usage: ./check-cve-2026-59208.sh [n8n_base_url]
set -u
BASE_URL="${1:-http://127.0.0.1:5678}"
STATUS="UNKNOWN"
ver_lt() {
# returns 0 if $1 < $2 (semver-ish)
[ "$1" = "$2" ] && return 1
printf '%s\n%s\n' "$1" "$2" | sort -V | head -1 | grep -qx "$1"
}
# 1. Try to read installed version
VER=""
if command -v n8n >/dev/null 2>&1; then
VER=$(n8n --version 2>/dev/null | tr -d 'v ')
fi
if [ -z "$VER" ]; then
VER=$(curl -fsS "${BASE_URL}/rest/settings" 2>/dev/null \
| grep -oE '"versionCli"[^,]+' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
fi
if [ -z "$VER" ]; then
echo "Could not determine n8n version."
echo "STATUS=UNKNOWN"
exit 2
fi
echo "Detected n8n version: $VER"
# 2. Version gate — vulnerable if <2.27.4, OR ==2.28.0
VULN=0
if ver_lt "$VER" "2.27.4"; then VULN=1; fi
if [ "$VER" = "2.28.0" ]; then VULN=1; fi
if [ $VULN -eq 0 ]; then
echo "Version is patched."
echo "STATUS=PATCHED"
exit 0
fi
# 3. Config gate — flaw only reachable with >1 trusted issuer
ISSUERS="${N8N_TOKEN_EXCHANGE_ISSUERS:-}"
if [ -z "$ISSUERS" ] && [ -f "${N8N_CONFIG_FILE:-/dev/null}" ]; then
ISSUERS=$(grep -Ei 'token[_-]?exchange.*issuer' "$N8N_CONFIG_FILE" | tr ',' '\n' | wc -l)
fi
COUNT=$(echo "$ISSUERS" | tr ',' '\n' | grep -c .)
if [ "$COUNT" -ge 2 ]; then
echo "Vulnerable version AND $COUNT trusted issuers configured."
echo "STATUS=VULNERABLE"
exit 1
elif [ "$COUNT" -eq 1 ]; then
echo "Vulnerable version but only 1 issuer — exploitation preconditions not met."
echo "STATUS=PATCHED" # effectively not reachable
exit 0
else
echo "Vulnerable version, issuer count unknown — treat as potentially vulnerable."
echo "STATUS=UNKNOWN"
exit 2
fi
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.