Auth Bypass in Express (Javascript)
Javascript-Specific Remediation in Express — concrete code fixes
Express.js applications often implement authentication middleware using simple token checks or session validation. A common auth bypass occurs when developers rely on client-controlled data to determine authorization state without proper server-side verification. For example, using a query parameter like ?role=admin or a header like X-User-Role: admin to grant elevated privileges creates an immediate bypass vector if the server trusts this input without validating against a trusted source such as a database or signed token.
In JavaScript, the dynamic nature of objects and loose equality comparisons (==) can exacerbate this issue. Consider an Express route that checks req.user.role == 'admin'. If req.user.role is derived from unverified input (e.g., parsed from a JWT without signature validation or taken directly from cookies), an attacker can manipulate the role value. Furthermore, JavaScript’s type coercion means values like 0, '', or false may evaluate unexpectedly in conditional checks, potentially bypassing role-based guards.
Another frequent flaw involves middleware ordering. If authentication middleware is placed after route-defining middleware or conditional logic, certain endpoints may skip authentication entirely. For instance, defining a public route before auth middleware applies it globally can leave sensitive paths exposed. Similarly, mounting routers with app.use('/api', apiRouter) without ensuring auth middleware is applied at the router level can result in inconsistent protection.
These issues are detectable via black-box scanning. middleBrick’s unauthenticated API scan tests for such bypass attempts by manipulating headers, query parameters, and cookies to observe whether access controls can be circumvented without valid credentials, reporting findings under the BOLA/IDOR and Property Authorization checks.
Javascript-Specific Remediation in Express — concrete code fixes
To prevent auth bypass in Express applications, enforce strict server-side validation of identity and roles using trusted sources. Never rely on client-supplied role indicators. Instead, decode and validate signed tokens (e.g., JWT) using a secret or public key, then fetch user details from a database or session store. Use libraries like jsonwebtoken with verification options to prevent algorithm confusion or tampering.
Example of secure middleware:
const jwt = require('jsonwebtoken');
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) return res.sendStatus(401);
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err) return res.sendStatus(403);
// Attach verified user payload; never trust client roles
req.user = { id: user.id, username: user.username };
next();
});
}
// Role-based authorization middleware
function authorizeRole(requiredRole) {
return (req, res, next) => {
// Fetch role from database using verified user ID
// Example: async lookup
getUserRoleFromDB(req.user.id)
.then(role => {
if (role !== requiredRole) {
return res.status(403).send('Insufficient permissions');
}
next();
})
.catch(() => res.status(500).send('Internal error'));
};
}
// Usage
app.get('/admin/users', authenticateToken, authorizeRole('admin'), (req, res) => {
res.json({ message: 'Admin only data' });
});
This ensures role checks are based on server-stored data, not client input. Additionally, avoid loose equality; use === for strict type-safe comparisons. Apply authentication middleware globally or at the router level before defining routes to prevent accidental exposure. For example:
const apiRouter = express.Router();
apiRouter.use(authenticateToken); // Protect all routes in this router
app.use('/api', apiRouter);
These practices eliminate reliance on client-controlled attributes and ensure authorization decisions are made only after verifying identity through trusted, server-side channels.
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 |