CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-VJF3-2GPJ-233V
4.3

The Backdoor in the Settings Menu: Bypassing n8n SSO

Alon Barad
Alon Barad
Software Engineer

Feb 27, 2026·7 min read·4 visits

PoC Available

Executive Summary (TL;DR)

Authenticated users can opt themselves out of mandatory SSO by sending a crafted JSON payload to the user settings API. This enables local password login, bypassing corporate IdP controls.

A mass assignment vulnerability in n8n's self-service settings API allows authenticated users to bypass mandatory Single Sign-On (SSO) enforcement. By manipulating the `/me/settings` endpoint, users can enable local password authentication for their accounts, effectively circumventing identity provider controls and multi-factor authentication policies.

The Hook: The Keys to the Automation Kingdom

n8n has rapidly become the Swiss Army knife of the modern enterprise. It connects everything—your CRM, your Slack, your production databases, and that weird legacy API nobody understands. Because it sits at the intersection of all your critical data, securing access to n8n is paramount. For most organizations, that means one thing: Single Sign-On (SSO).

SSO is the bouncer at the club. It decides who gets in, checks their ID (authentication), and makes sure they aren't carrying weapons (authorization). When an admin enforces SSO, they are essentially saying, "Nobody gets in unless Okta/Google says so." It allows for centralized revocation, audit trails, and, crucially, Multi-Factor Authentication (MFA).

But what if the bouncer had a tip jar? What if you could just walk up to the velvet rope, slip the bouncer a twenty (or a JSON boolean), and have him wave you through the side door forever? That is exactly what GHSA-VJF3-2GPJ-233V allows. It is a logic flaw that lets any authenticated user whisper to the backend, "Hey, don't worry about that SSO stuff for me," and the backend simply nods and agrees.

The Flaw: A Classic Case of Overposting

This vulnerability is a textbook example of Mass Assignment, also known as Overposting (CWE-915). In modern web frameworks, developers often use Data Transfer Objects (DTOs) to define the shape of incoming data. A lazy or efficient (depending on your cynicism) developer might define a single DTO for a user entity and reuse it across multiple endpoints—creation, admin updates, and self-service updates.

The problem arises when that DTO includes fields that should never be touched by a standard user. In n8n's case, the MeController, which handles the /me endpoints for the currently logged-in user, was reusing a DTO intended for administrative actions. This DTO contained the keys to the castle, specifically a property called allowSSOManualLogin.

Here is the logic gap: The endpoint /me/settings is designed to let you change benign preferences, like whether you want to see the "Welcome to AI" onboarding modal. However, because the backend blindly accepted the entire DTO and merged it into the user's record in the database, it didn't just update the UI preferences. It updated everything you sent it, provided the field existed in the schema. It's akin to filling out a change-of-address form at the bank, writing "Account Balance: $1,000,000" in the margin, and having the teller update your ledger because they didn't check which fields were read-only.

The Code: One DTO to Rule Them All

The smoking gun lies in packages/cli/src/controllers/me.controller.ts. Prior to version 2.8.0, the code handling user updates looked something like this (simplified for clarity):

// VULNERABLE CODE
@Patch('/settings')
async updateCurrentUserSettings(
    req: AuthenticatedRequest,
    _: Response,
    // The flaw: Using the Admin-level DTO for a user-level endpoint
    @Body payload: SettingsUpdateRequestDto,
): Promise<User['settings']> {
    const { id } = req.user;
    // The payload is passed directly to the service layer
    return await this.usersService.updateSettings(id, payload);
}

The SettingsUpdateRequestDto was a wide-open door. It included fields that controlled security policies. The fix, implemented in commit a70b2ea379086da3de103bb84811e88cadf29976, was to introduce a strict whitelist. The developers created a new DTO specifically for self-service updates.

// FIXED CODE
// packages/@n8n/api-types/src/dto/user/user-self-settings-update-request.dto.ts
export class UserSelfSettingsUpdateRequestDto extends Z.class({
    // Only benign fields are allowed here
    easyAIWorkflowOnboarded: z.boolean().optional(),
    dismissedCallouts: z.record(z.string(), z.boolean()).optional(),
}) {}
 
// packages/cli/src/controllers/me.controller.ts
@Patch('/settings')
async updateCurrentUserSettings(
    req: AuthenticatedRequest,
    _: Response,
    // The fix: Using the restricted DTO
    @Body payload: UserSelfSettingsUpdateRequestDto,
): Promise<User['settings']> {
    // ...
}

By switching the type definition in the controller method signature, the framework's validation layer (Zod) now automatically strips out any field not explicitly defined in UserSelfSettingsUpdateRequestDto. If a hacker tries to send allowSSOManualLogin, the validator effectively ignores it before it ever reaches the database logic.

The Exploit: Opting Out of Security

Exploiting this is trivially easy for anyone who already has access (or has compromised a low-level account). You don't need buffer overflows or heap spraying; you just need curl or Burp Suite.

Scenario: You are an employee at a company enforcing strict SSO via Okta. You want to maintain access even if your Okta account is suspended, or perhaps you just hate 2FA. You are currently logged in.

Step 1: Intercept the request when you change a setting in the UI, or construct a fresh one.

Step 2: Send the payload with the forbidden flag.

PATCH /me/settings HTTP/1.1
Host: n8n.corp.internal
Authorization: Bearer <YOUR_JWT_TOKEN>
Content-Type: application/json
 
{
    "allowSSOManualLogin": true,
    "easyAIWorkflowOnboarded": true
}

Step 3: The server responds with 200 OK. The database now has your user record marked as allowed to use manual login.

Step 4: You can now set a local password (if you haven't already) or use the "Forgot Password" flow to establish one. From this point forward, you can log in directly at the /login page, completely bypassing the "Log in with SSO" button and any MFA checks associated with the IdP.

The Impact: Persistence and Shadow Access

While the CVSS score is a moderate 4.3 (due to the requirement of prior authentication), the practical impact for an enterprise is significant. This is a Persistence technique.

Imagine an insider threat scenario: An employee is about to be fired. Knowing their access will be revoked in the Identity Provider (IdP) at 5:00 PM, they execute this exploit at 4:55 PM. At 5:01 PM, the sysadmin kills their Okta account. The employee goes home, opens n8n, types in their local email and password, and they are back in. They still have access to all the API keys, credentials, and workflows stored in n8n.

Furthermore, this breaks the chain of trust. Security compliance standards (SOC2, ISO27001) often rely on the assertion that "Access is strictly controlled via SSO with MFA." This vulnerability proves that assertion false for the affected versions. A user could theoretically have a weak password like password123 on a system protecting production database credentials, and the security team would be none the wiser because they believe SSO is enforcing strong auth.

The Fix: Closing the Loophole

Remediation is straightforward but requires action on two fronts: patching the code and scrubbing the data.

1. Patching: Upgrade to n8n version 2.8.0 or later immediately. This version introduces the DTO segregation that physically prevents the API from accepting the malicious field.

2. Hunting: Patching stops new exploits, but it does not revert changes made by past exploits. If a malicious user has already flipped this bit, upgrading the software might not reset it (depending on how the migration scripts are written, but usually, user data is preserved). You must audit your database.

Run the following SQL query against your n8n postgres database to find users who have effectively opted out of SSO:

SELECT id, email, "firstName", "lastName"
FROM "user"
WHERE "settings"->>'allowSSOManualLogin' = 'true'
AND "role" != 'global:owner'; -- Assuming owners might legitimately have this

If you find any non-admin users in this list, reset their settings immediately and investigate their activity logs.

Official Patches

n8nn8n version 2.8.0 Release Notes
GitHubFix Commit

Fix Analysis (1)

Technical Appendix

CVSS Score
4.3/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N

Affected Systems

n8n workflow automation platform (self-hosted)n8n cloud (prior to fix)

Affected Versions Detail

Product
Affected Versions
Fixed Version
n8n
n8n.io
< 2.8.02.8.0
AttributeDetail
CWE IDCWE-915 (Mass Assignment)
CVSS v3.14.3 (Medium)
Attack VectorNetwork (Authenticated)
ImpactSecurity Policy Bypass (SSO/MFA)
Patch Commita70b2ea379086da3de103bb84811e88cadf29976
Fixed Version2.8.0

MITRE ATT&CK Mapping

T1548.002Abuse Elevation Control Mechanism: Bypass User Account Control
Privilege Escalation
T1078Valid Accounts
Defense Evasion
CWE-915
Improperly Controlled Modification of Dynamically-Determined Object Attributes

The software allows the user to modify object attributes that should be restricted, leading to unauthorized changes in security settings.

Known Exploits & Detection

Internal ResearchThe exploit logic is derived directly from the patch which removes the ability to set the 'allowSSOManualLogin' flag via the self-service endpoint.

Vulnerability Timeline

Fix commit merged to master
2026-02-05
Version 2.8.0 released
2026-02-05
GHSA Advisory Published
2026-02-25

References & Sources

  • [1]GHSA-VJF3-2GPJ-233V: SSO Enforcement Bypass
  • [2]CWE-915: Mass Assignment

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.