CVEReports
CVEReports

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

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-22032

Directus to Anywhere: Riding the SAML RelayState Express (CVE-2026-22032)

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 24, 2026·6 min read·44 visits

Executive Summary (TL;DR)

Improper validation in Directus' SAML callback allowed attackers to abuse the `RelayState` parameter. An attacker could craft a login link that, after a successful SSO authentication, redirects the victim to an external site (e.g., a credential harvester). Fixed in version 11.14.0.

Directus, the beloved 'headless' wrapper for your SQL databases, suffered from a classic Open Redirect vulnerability within its SAML authentication driver. By manipulating the `RelayState` parameter during the Single Sign-On (SSO) flow, attackers could weaponize a trusted Directus instance to bounce authenticated users to malicious domains. While the vulnerability is technically 'medium' severity, its utility in high-end phishing campaigns makes it a dangerous tool in the wrong hands.

The Hook: Trust, Verify, Then Redirect?

Directus is the darling of the modern stack—a sleek, real-time API and dashboard that turns any SQL database into a headless CMS. It’s the kind of tool developers love because it 'just works.' But when you start integrating enterprise protocols like SAML (Security Assertion Markup Language), 'just working' isn't enough; it needs to just work securely.

SAML is a beast of a protocol. It involves a three-way dance between the User, the Service Provider (Directus), and the Identity Provider (IdP, like Okta or Auth0). One critical component of this dance is maintaining state. If I try to access a specific dashboard page but haven't logged in, the application sends me to the IdP. Once I authenticate, the application needs to remember where I wanted to go. Enter the RelayState parameter.

RelayState is essentially a bookmark. It travels from the Service Provider to the IdP and comes back unchanged. It’s the digital equivalent of a coat check ticket. The problem with CVE-2026-22032 is that Directus trusted this ticket implicitly. If the ticket said 'give this person the coat belonging to the bank robber,' Directus happily obliged.

The Flaw: The Unchecked Return Trip

The vulnerability lies within the logic gap between initiation and callback. When a user starts a SAML login flow, Directus constructs a SAML Request and sends the user to the IdP. It allows a redirect URL to be embedded in the RelayState so the user lands on the right page after login.

The developers implemented validation logic during the initiation phase (when generating the request). However, they forgot the golden rule of web security: never trust input, even if you think you generated it. The vulnerability existed in the Assertion Consumer Service (ACS)—the callback endpoint where the IdP returns the user.

When the IdP POSTs the SAML Response back to Directus, it includes the RelayState. The Directus SAML driver (api/src/auth/drivers/saml.ts) would parse this response, log the user in, and then—without a second glance—issue an HTTP 302 Redirect to whatever URL was inside that RelayState. It didn't check if the URL was relative (e.g., /admin/content) or absolute (e.g., https://evil-phishing-site.com). This meant the validation at the start of the flow was irrelevant; if an attacker could inject a malicious URL into the RelayState passed to the callback, the game was over.

The Code: The Smoking Gun

Let’s look at the code. This is a textbook example of a missing safeguard. In the vulnerable versions (pre-11.14.0), the SAML driver handled the success path like this:

// The Vulnerable Logic (Pseudo-code representation)
async callback(req, res) {
    const { relayState } = req.body;
    // ... perform authentication ...
    
    // The Fatal Flaw: Blindly redirecting
    if (relayState) {
        return res.redirect(relayState);
    }
    return res.redirect('/');
}

The fix, introduced in commit dad9576ea9362905cc4de8028d3877caff36dc23, forces the application to verify the destination against a strict allowlist (usually the application's own public URL). It introduces a utility function isLoginRedirectAllowed.

// The Fix in api/src/auth/drivers/saml.ts
 
// ... inside the callback handler ...
 
if (relayState && isLoginRedirectAllowed(relayState, providerName) === false) {
    // 🛑 STOP RIGHT THERE, CRIMINAL SCUM
    throw new InvalidPayloadError({
        reason: `URL "${relayState}" can't be used to redirect after login` 
    });
}
 
// proceed to redirect only if valid

This simple check ensures that the relayState is either a relative path or matches the configured PUBLIC_URL of the Directus instance. If it points to an external domain not explicitly allowed, it throws an error.

The Exploit: Bouncing to Evil.com

Exploiting this is trivially easy and highly effective for social engineering. The goal is to create a link that looks legitimate (it points to the company's Directus instance) but lands the user on a phishing page.

The Attack Chain:

  1. Reconnaissance: The attacker identifies a target organization using Directus with SAML enabled (e.g., https://cms.target-corp.com).
  2. Crafting the Link: The attacker creates a URL that initiates the SAML login but specifies a malicious redirect. Depending on how Directus parses the initial request to build the RelayState, this might look like: https://cms.target-corp.com/auth/login/saml?redirect=https://evil-phishing.com/login
  3. The Hook: The attacker sends this link to an employee via email: "Urgent: Please review the Q1 content updates on the CMS."
  4. The Bait: The victim clicks. They see the legitimate Directus URL. They are redirected to their corporate IdP (Okta/Azure AD). They sign in with valid credentials.
  5. The Switch: The IdP sends them back to Directus. Directus authenticates them, reads the RelayState (https://evil-phishing.com/login), and issues a 302 Found.
  6. The Catch: The victim lands on evil-phishing.com, which is styled exactly like the Directus dashboard but asks for a "session re-verification." The victim enters their creds again. Game over.

Because the redirect happens after a valid login, the user's suspicion is at an absolute minimum. It feels like a standard SSO quirk.

The Impact: Why We Should Care

CVSS scores often mislead. A score of 4.3 (Medium) suggests this is a "fix it next month" problem. It isn't. Open Redirects are force multipliers for other attacks.

In a corporate environment, trust is the perimeter. Users are trained to check the URL bar. This exploit allows an attacker to start the interaction on a trusted, green-lock domain. It bypasses the first line of human defense.

Furthermore, this wasn't just on successful logins. The vulnerability existed in error handling paths too. Even if the user cancelled the login at the IdP, Directus might still process the RelayState and redirect them, meaning the attack doesn't even strictly require valid credentials to work as a redirector.

The Fix: Upgrade or Die (Redirecting)

The remediation is straightforward: Update Directus to version 11.14.0 or higher immediately.

If you are stuck on an older version and cannot upgrade (why?), you might be able to mitigate this at the network level, but it's messy. You would need WAF rules that inspect the RelayState parameter in POST requests to /auth/login/saml/callback and block anything looking like an external absolute URL.

Post-patch, ensure your PUBLIC_URL environment variable is set correctly. This variable is the source of truth for the new validation logic. If you do need to redirect to external domains (e.g., multiple micro-frontends), you must now explicitly list them in AUTH_SAFE_REDIRECT_URLS. Directus has moved from a "permissive by default" to a "secure by default" stance here, which is exactly what we want to see.

Official Patches

DirectusDirectus v11.14.0 Release Notes

Fix Analysis (1)

Technical Appendix

CVSS Score
4.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N
EPSS Probability
0.09%
Top 75% most exploited

Affected Systems

Directus CMSDirectus API

Affected Versions Detail

Product
Affected Versions
Fixed Version
Directus
Directus
< 11.14.011.14.0
AttributeDetail
CWE IDCWE-601
CVSS Score4.3 (Medium)
Attack VectorNetwork (Authentication Required for full chain)
EPSS Score0.00087
Exploit StatusPoC Available
ImpactPhishing Facilitation

MITRE ATT&CK Mapping

T1566.002Spearphishing Link
Initial Access
T1204.001User Execution: Malicious Link
Execution
CWE-601
Open Redirect

URL Redirection to Untrusted Site ('Open Redirect')

Known Exploits & Detection

GitHub AdvisoryOfficial advisory containing reproduction steps

Vulnerability Timeline

Fix committed to repository
2025-12-09
Vulnerability publicly disclosed
2026-01-08
GHSA Advisory Published
2026-01-08

References & Sources

  • [1]GHSA-3573-4c68-g8cc
  • [2]NVD - CVE-2026-22032

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.

More Reports

•1 day ago•GHSA-7PPR-R889-MCF2
7.5

GHSA-7PPR-R889-MCF2: Unbounded WebSocket Message Aggregation in http4s-blaze-server leads to Denial of Service

An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.

Alon Barad
Alon Barad
7 views•5 min read
•1 day ago•GHSA-95CV-R8X4-VH75
7.6

GHSA-95cv-r8x4-vh75: Path Traversal Vulnerability in OpenList Batch Rename Handler

A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.

Amit Schendel
Amit Schendel
7 views•7 min read
•1 day ago•GHSA-P6PH-3JX2-3337
4.3

GHSA-P6PH-3JX2-3337: Horizontal Privilege Escalation and Metadata Information Disclosure via Bleve Search in OpenList

OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.

Amit Schendel
Amit Schendel
7 views•5 min read
•1 day ago•GHSA-86CX-WWF4-PHQ4
6.5

GHSA-86cx-wwf4-phq4: Path Prefix Confusion Authorization Bypass in OpenList

An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.

Amit Schendel
Amit Schendel
6 views•6 min read
•1 day ago•CVE-2026-16584
7.0

CVE-2026-16584: Security Policy Bypass in AWS API MCP Server via Startup Initialization Failure

A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.

Amit Schendel
Amit Schendel
10 views•7 min read
•1 day ago•GHSA-6V4M-FW66-8R4X
6.5

GHSA-6V4M-FW66-8R4X: Path Disclosure and Shell Expansion Bypass in Shescape

An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.

Alon Barad
Alon Barad
6 views•7 min read