XSS Labs

Multiple XSS Challenges with Different Filtering Methods

Multiple Challenge Interface

Lab Overview

This interface contains two different XSS challenges with different filtering approaches:

Challenge 1: Basic HTML encoding using htmlspecialchars() for both first name and last name parameters.
Challenge 2: String replacement filter for the 'p' parameter that removes various script tag variations and other HTML tags.
Challenge 2 Filter: Blocks case variations of 'script' plus 'img', 'image', 'svg', 'audio', 'video', 'body'
Blocked tags:
script
sCript
scRipt
scrIpt
scriPt
scripT
SCript
SCRipt
SCRIpt
SCRIPt
SCRIPT
img
image
svg
audio
video
body
Filter method: str_replace(array('script','sCript',...,'body'), '', $_GET['p'])
Filter Complexity: Tag Filtering with Case Variations

Objective: Test different XSS payloads against both filtering methods to understand their effectiveness.

Backend Source Code
if(isset($_GET["fname"]) && isset($_GET["lname"])){
    echo htmlspecialchars($_GET["fname"], ENT_QUOTES);
    echo htmlspecialchars($_GET["lname"], ENT_QUOTES);
}
elseif(isset($_GET["p"])){
    $arr = array('script','sCript','scRipt','scrIpt','scriPt','scripT','SCript','SCRipt','SCRIpt','SCRIPt','SCRIPT',
    'img','image','svg','audio','video','body');
    $re = str_replace($arr, '', $_GET['p']);
    echo $re;
}
Test Input Forms
Challenge 1: HTML Encoding
This field uses htmlspecialchars() encoding
This field uses htmlspecialchars() encoding

Challenge 2: String Replacement Filter
This field uses str_replace() filtering
XSS Bypass Techniques for Challenge 2
  • Case variation: Try ScRiPt or other mixed case variations not in the filter
  • Nested tags: Use <scr<script>ipt> to bypass simple filters
  • Alternative tags: Use <object>, <embed>, <iframe> instead of script tags
  • Event handlers: Use <img src=x onerror=alert(1)> or other event-based XSS
  • JavaScript protocol: Use <a href="javascript:alert(1)">click</a>
  • SVG vectors: Use <svg onload=alert(1)> if svg is not filtered
  • Encoding: Use HTML entities, URL encoding, or Unicode escapes
  • String concatenation: Build the script tag dynamically: <scr"+"ipt>
Security Implications

Comparing the two filtering approaches:

  • HTML Encoding (Challenge 1): Properly implemented with htmlspecialchars() and ENT_QUOTES flag
  • String Replacement (Challenge 2): Incomplete filtering that can be bypassed with creative techniques
  • Blacklist approaches are always vulnerable to bypass techniques
  • Context-aware output encoding is the only reliable defense
  • Filtering should happen at the output stage, not input stage
Best Practices

For production-grade XSS prevention:

  • Always use context-aware output encoding
  • Implement strict Content Security Policy (CSP) headers
  • Validate input using strict whitelists, not blacklists
  • Use modern sanitization libraries (DOMPurify, etc.)
  • Implement Trusted Types for DOM XSS protection
  • Use security headers: X-XSS-Protection, X-Content-Type-Options
  • Conduct regular security testing and code reviews