Cross-Site Scripting (XSS) is one of the most common and dangerous security vulnerabilities in web applications. It allows attackers to inject malicious scripts into web pages viewed by other users.

If exploited, XSS can:

  • Steal cookies, session tokens, or sensitive data
  • Deface websites
  • Redirect users to malicious sites
  • Perform actions on behalf of the victim

In this article, we'll:

  1. Understand what XSS is and its types
  2. See realistic examples
  3. Learn how to detect and prevent it using Python

⚠️ What is XSS?

XSS occurs when a web application includes untrusted user input in its output without proper validation or escaping. This allows attackers to run arbitrary JavaScript in the victim's browser.

Example:

<!-- Vulnerable code -->
<p>Welcome, <?php echo $_GET['name']; ?></p>

If a user visits:

https://example.com/?name=<script>alert('Hacked!')</script>

The browser will execute the injected script.

🧩 Types of XSS

There are three main types:

1. Stored XSS

  • Malicious script is permanently stored on the server (e.g., in a database, comment section).
  • Every time a user loads the page, the script executes.

2. Reflected XSS

  • Malicious script is reflected off the server in an immediate response (e.g., search results, error messages).
  • Triggered by clicking a crafted link.

3. DOM-based XSS

  • The vulnerability exists in the client-side JavaScript.
  • The script modifies the DOM without proper sanitization.

🐍 Detecting XSS with Python

We can write a simple Python scanner to test for XSS vulnerabilities.

import requests

# Target URL (vulnerable parameter)
url = "http://example.com/search"

# Common XSS payloads
payloads = [
    "<script>alert('XSS')</script>",
    "\"><img src=x onerror=alert('XSS')>",
    "';alert(String.fromCharCode(88,83,83));//"
]

for payload in payloads:
    params = {"q": payload}
    r = requests.get(url, params=params)
    if payload in r.text:
        print(f"[!] Possible XSS vulnerability with payload: {payload}")
    else:
        print(f"[-] No reflection for payload: {payload}")

How it works:

  • Sends payloads to the target parameter
  • Checks if the payload is reflected in the response
  • If found, it may indicate a vulnerability

✅ Preventing XSS

To protect against XSS:

  • Escape output: Encode special characters before rendering
  • Validate input: Reject unexpected characters or HTML tags
  • Use security libraries: For example, Django and Flask have built-in escaping
  • Implement Content Security Policy (CSP): Restrict what scripts can run

Example: Escaping in Python Flask

from flask import Flask, request, escape

app = Flask(__name__)

@app.route("/")
def home():
    name = request.args.get("name", "")
    safe_name = escape(name)  # Escapes HTML special characters
    return f"<p>Welcome, {safe_name}</p>"

if __name__ == "__main__":
    app.run(debug=True)

Here, escape() ensures that <script> tags are displayed as text, not executed.

🛡️ XSS Prevention Checklist

  • ✅ Always escape user input before rendering
  • ✅ Use frameworks' built-in XSS protection
  • ✅ Validate and sanitize input
  • ✅ Avoid innerHTML in JavaScript (use textContent instead)
  • ✅ Implement CSP headers

📖 Conclusion

XSS is easy to exploit but also easy to prevent with the right coding practices. By validating input, escaping output, and using secure frameworks, you can protect your users and your application from one of the most prevalent web vulnerabilities.