Xss Cross Site Scripting in Express with Bearer Tokens
Xss Cross Site Scripting in Express with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Cross-site scripting (XSS) in an Express API that uses Bearer token authentication commonly arises when the API reflects untrusted data into HTML or JavaScript contexts without proper encoding, and the client-side consumes responses that include sensitive authorization metadata. Bearer tokens themselves are not inherently unsafe, but mishandling token leakage in responses or logs can expose credentials that facilitate further exploitation. For example, if an Express endpoint accepts user-controlled query parameters or request bodies and embeds them directly into HTML or JSON responses that are later rendered in a browser, an attacker may inject scripts that execute in the context of other users’ sessions.
When an API uses Bearer tokens for authorization, developers sometimes include the token or parts of it in error messages, URLs, or JSON payloads returned to clients. If those responses are rendered in a browser—such as a single-page application (SPA) that displays user-provided content—reflected XSS becomes possible. Consider an endpoint that echoes a search term without sanitization and also returns a token in a custom header or JSON field; an attacker could craft a URL containing a malicious script and a valid token, tricking a victim into visiting the link and inadvertently executing the injected script within the victim’s authenticated session.
Another vector involves logging or debugging mechanisms in Express that inadvertently include Authorization headers. If log entries containing Bearer tokens are exposed through an information disclosure vulnerability, these logs can become a source of sensitive data that attackers harvest to build more sophisticated XSS or token replay attacks. Even when the API itself does not render HTML, an XSS flaw in a consuming client (such as a dashboard that renders JSON responses as HTML) can be triggered by carefully crafted data combined with a valid Bearer token that grants access to privileged endpoints.
In the context of the OWASP API Top 10, XSS maps to Injection and Broken Function Level Authorization when malicious input is processed in an unsafe manner. In an Express application, common root causes include failing to set proper Content-Type headers, neglecting to encode output in HTML/JavaScript/CSS contexts, and trusting data from headers or cookies without validation. Because Bearer tokens often appear in Authorization headers, any leakage or improper handling increases the impact of XSS by providing a pathway for session hijacking or privilege escalation.
Bearer Tokens-Specific Remediation in Express — concrete code fixes
To mitigate XSS risks while using Bearer tokens in Express, focus on strict input validation, secure header handling, and safe output encoding. Avoid reflecting tokens in responses, and ensure that any data used in HTML, JavaScript, or JSON is properly sanitized. Below are concrete patterns and code examples that reduce the likelihood of token-related XSS.
1. Do not expose Bearer tokens in responses or logs
Ensure middleware and error handlers do not include Authorization headers in responses or logs. Explicitly strip or redact sensitive headers before logging.
const sensitiveHeaders = new Set(['authorization', 'cookie']);
app.use((req, res, next) => {
const filteredHeaders = {};
for (const [key, value] of Object.entries(req.headers)) {
filteredHeaders[key] = sensitiveHeaders.has(key.toLowerCase()) ? '[REDACTED]' : value;
}
console.log('Incoming request headers:', filteredHeaders);
next();
});
2. Use secure Content-Type and output encoding for user data
When sending JSON responses, set the correct Content-Type and avoid injecting raw user input into JavaScript blocks. If you must embed data in HTML, use a trusted templating engine with automatic escaping or manually encode special characters.
const escapeHtml = (unsafe) => {
if (typeof unsafe !== 'string') return '';
return unsafe.replace(/[<>"'&]/g, (char) => ({
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
}[char]));
};
app.get('/search', (req, res) => {
const query = req.query.q || '';
const safeQuery = escapeHtml(query);
res.setHeader('Content-Type', 'application/json; charset=utf-8');
res.end(JSON.stringify({ message: `Search results for: ${safeQuery}` }));
});
3. Validate and restrict Authorization header usage
Verify that Bearer tokens follow expected formats and reject malformed or suspicious values. Do not rely solely on the presence of a token; validate scopes and permissions as appropriate for each endpoint.
const bearerRegex = /^Bearer [A-Za-z0-9._\-]+\.[A-Za-z0-9._\-]+\.?[A-Za-z0-9._\-=+/]*$/;
const authenticate = (req, res, next) => {
const authHeader = req.headers.authorization || '';
if (!bearerRegex.test(authHeader)) {
return res.status(401).json({ error: 'Invalid authorization header format' });
}
const token = authHeader.split(' ')[1];
// Perform token verification with your auth provider here
if (!isValidToken(token)) {
return res.status(403).json({ error: 'Invalid token' });
}
req.user = { tokenScope: 'read' }; // example claim extraction
next();
};
app.use('/api', authenticate);
4. Apply security headers and CSP where applicable
Even when your API does not render HTML, clients consuming the API may embed responses in browser contexts. Setting security headers reduces the impact of accidental HTML rendering.
app.use((req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "default-src 'none'; script-src 'none'; style-src 'none'");
next();
});
5. Use the CLI and dashboard to track security posture
You can scan your Express endpoints with the CLI to identify XSS and token handling issues, and track findings over time in the Dashboard. For example, run a scan from the terminal with middlebrick scan <url>, or integrate the GitHub Action to fail builds if risk scores drop below your chosen threshold. The Pro plan enables continuous monitoring and CI/CD pipeline gates, helping you catch regressions before deployment.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |