01Summary

Cross-Site Scripting (XSS) occurs when user input is displayed on a web page without being properly sanitized or encoded, allowing an attacker to inject malicious scripts that execute in other users' browsers. This is one of the most common web vulnerabilities and can lead to session hijacking, credential theft, malware distribution, and defacement.

02How It Happens

Web applications often accept user input—from form fields, URL parameters, file uploads, or database records—and display it back to users in HTML pages. If the application does not encode or filter this input before rendering it, an attacker can embed JavaScript code that the browser will execute as if it were part of the legitimate page. The attacker's script runs with the same privileges as the legitimate page, including access to cookies, session tokens, and sensitive DOM data. There are three main variants: stored XSS (malicious input saved to a database and served to all visitors), reflected XSS (malicious input echoed back in the same response), and DOM-based XSS (client-side JavaScript mishandles untrusted data).

03Real-World Impact

An attacker exploiting XSS can steal session cookies to impersonate users, capture login credentials entered on the page, redirect users to phishing or malware sites, deface page content, or perform actions on behalf of the victim (such as changing account settings or posting content). In high-value targets like banking or email platforms, XSS can lead to complete account compromise. Even on lower-risk sites, XSS can damage user trust and expose sensitive information.

04Vulnerable & Fixed Patterns

Vulnerable pattern
from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route('/comment')
def show_comment():
    user_comment = request.args.get('text', '')
    html = f"<p>User said: {user_comment}</p>"
    return render_template_string(html)

Why it's vulnerable:
The user input from the text parameter is directly interpolated into HTML without encoding. An attacker can pass text=<script>alert('XSS')</script> and the script will execute in the victim's browser.

Fixed pattern
from flask import Flask, request, render_template_string
from markupsafe import escape

app = Flask(__name__)

@app.route('/comment')
def show_comment():
    user_comment = request.args.get('text', '')
    safe_comment = escape(user_comment)
    html = f"<p>User said: {safe_comment}</p>"
    return render_template_string(html)  
Vulnerable pattern
<?php
$user_input = $_GET['message'] ?? '';
echo "<div class='post'>";
echo "User message: " . $user_input;
echo "</div>";
?>

Why it's vulnerable:
The $_GET parameter is echoed directly into the HTML output without escaping. An attacker can inject <img src=x onerror=\"alert('XSS')\"> and the browser will execute the JavaScript.

Fixed pattern
<?php
$user_input = $_GET['message'] ?? '';
echo "<div class='post'>";
echo "User message: " . esc_html($user_input);
echo "</div>";
?>

05Prevention Checklist

Encode output context-aware:
Use esc_html() for HTML content, esc_attr() for HTML attributes, esc_js() for JavaScript strings, and esc_url() for URLs. The encoding method depends on where the data appears in the page.
Use templating engines with auto-escaping:
Modern frameworks (Flask with Jinja2, Django, etc.) escape by default; ensure auto-escaping is enabled and not bypassed.
Implement Content Security Policy (CSP):
Set a strict CSP header to restrict script execution to trusted sources, reducing the impact of injected scripts.
Validate and sanitize input:
Reject or strip unexpected characters and tags. Use allowlists (e.g., only alphanumeric and spaces) when possible.
Avoid dangerous functions:
Never use eval(), innerHTML, or render_template_string() with user input. Use safe DOM methods like textContent or innerText.
Test with automated scanners:
Use SAST tools and browser-based XSS scanners to detect unencoded output during development.

06Signs You May Already Be Affected

Check your application logs for unusual JavaScript patterns in request parameters or POST bodies (e.g., <script>, onerror=, onclick=). Review your database for stored comments or user-generated content that contains HTML or script tags. If users report unexpected pop-ups, redirects, or page content changes, investigate whether malicious scripts have been injected into your pages.

07Related Recent Vulnerabilities