I created a simple Flask view that echoed user input, used it to demonstrate reflected XSS in a safe environment, then implemented layered defenses. I verified the fix and documented the patterns that keep templates safe by default. (How to Prevent Cross-Site Scripting)
Reproduce reflected XSS in a controlled lab
Apply output encoding and safer templating
Add a basic Content Security Policy
Show before and after behavior clearly
Python and Flask basics
Familiarity with HTML templates and forms
Flask, Jinja templates
Browser developer tools for testing and headers inspection
1. Target setup
Built a minimal search form that returned user input to the page
Confirmed the vulnerable behavior in a local environment
2. Primary mitigation
Replaced direct string rendering with a template and ensured variables are auto-escaped
Used explicit escaping for any dynamic content that might be unsafe
3. Defense in depth
Added a simple Content Security Policy set to same origin
Reviewed templates for unsafe constructs and disabled debug for production
4. Verification and docs
Repeated the test input and confirmed it now renders as plain text
Documented patterns for safe rendering and CSP benefits
Eliminated reflected XSS in the demo route
Captured simple rules that keep templates safe
Added a reusable security header pattern
XSS testing in a safe lab
Secure templating and output encoding
HTTP response hardening with CSP