Auth Bypass in Adonisjs with Saml
Auth Bypass in Adonisjs with Saml — how this specific combination creates or exposes the vulnerability
AdonisJS is a Node.js web framework that often integrates third-party SAML libraries to handle SAML-based authentication. When SAML is implemented without strict validation of the SAML response and without enforcing proper session-state checks, an authentication bypass can occur. This typically happens when the application trusts the SAML assertion without verifying the issuer (entityID), audience (aud), or the digital signature of the SAML response. An attacker can supply a crafted SAML response that appears valid, leading the framework to create an authenticated session for an unauthorized identity or to skip required authentication checks entirely.
Another common vector is improper route protection. AdonisJS relies on middleware or route-level guards to enforce authentication. If routes that should require a verified SAML session are left unprotected, or if the middleware incorrectly evaluates session presence (for example, only checking for a local session flag and not the SAML session state), an unauthenticated user can access privileged endpoints. This is a BOLA/IDOR-like condition when ID values in URLs or parameters are used without validating that the requesting identity is tied to the resource.
Additionally, misconfigured SAML settings can contribute to bypass risks. For example, setting the audience to a broad or wildcard value, or failing to validate NameID format and attributes, can allow an attacker to reuse assertions across services. If the application does not enforce single logout (SLO) or does not invalidate local sessions upon SAML logout, stale sessions may remain active, enabling access after the identity’s SAML session has ended. These issues are detectable by security scans that test unauthenticated attack surfaces and analyze OpenAPI definitions alongside runtime behavior, highlighting weak authentication boundaries and missing authorization checks.
Saml-Specific Remediation in Adonisjs — concrete code fixes
To remediate SAML-related authentication bypass in AdonisJS, enforce strict validation of SAML responses and tighten route protection. Always verify the SAML response signature, validate the issuer (entityID), and ensure the audience (aud) matches your service provider identifier. Use a well-maintained SAML library such as @node-saml/passport-saml and configure it with explicit settings rather than relying on defaults.
Below is a concrete example of a SAML strategy configuration in AdonisJS that validates critical SAML parameters:
const SamlStrategy = require('@node-saml/passport-saml').Strategy;
const samlStrategy = new SamlStrategy(
{
entryPoint: 'https://idp.example.com/sso/saml',
issuer: 'https://sp.example.com/saml/metadata',
callbackUrl: 'https://sp.example.com/saml/acs',
cert: `-----BEGIN CERTIFICATE-----
MIIC...your-idp-certificate...
-----END CERTIFICATE-----`,
// Enforce strict audience and nameID validation
audience: 'https://sp.example.com/saml/metadata',
identifierFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
// Validate the SAML response signature and issuer
validateInResponseTo: true,
disableRequestedAuthnContext: false,
},
(profile, done) => {
// Ensure NameID is present and of expected format
if (!profile.nameID || !profile.nameID.includes('@')) {
return done(new Error('Invalid NameID format'), null);
}
// Map SAML attributes to a local user record securely
return done(null, { samlNameId: profile.nameID, attributes: profile.attributes });
}
);
module.exports = samlStrategy;
Next, protect routes using AdonisJS middleware that verifies an established SAML session. Do not rely solely on a local session flag. The following middleware checks for a valid SAML profile attached to the authentication context:
class EnsureSamlAuthenticated {
async handle({ auth, response }, next) {
// Ensure a SAML profile is present and verified
if (!auth.user || !auth.user.samlNameId) {
return response.status(401).send('Unauthorized: SAML session required');
}
// Optionally enforce additional attribute checks (roles, groups)
const hasAccess = await this.validateSamlAttributes(auth.user.attributes);
if (!hasAccess) {
return response.status(403).send('Forbidden: Insufficient SAML attributes');
}
await next();
}
}
module.exports = EnsureSamlAuthenticated;
Finally, enforce audience and issuer validation on the Service Provider side, and ensure logout flows terminate local sessions. When processing Single Logout (SLO), clear the local session to prevent stale access:
app.post('/saml/sls', async ({ session, response }) => {
// Invalidate local session upon SAML logout
session.logout();
response.redirect('/');
});
These steps reduce the risk of authentication bypass by ensuring SAML assertions are cryptographically validated, audiences and issuers are strictly checked, and protected routes require verified SAML sessions rather than weak local flags.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |