Reflected XSS Bootcamp

Lab: Character Replacement Filter Bypass

Difficulty: Medium

Lab Overview

This lab demonstrates a reflected XSS vulnerability with a character replacement filter that replaces all '<' characters with ';' in the First Name parameter.

Character Replacement Filter: All '<' characters are replaced with ';'
< ;

str_replace('<', ';', $_GET['fname'])

Filter Complexity: Character-Level Filtering

Objective: Bypass the character replacement filter and execute a JavaScript alert.

Note: Only the First Name field is filtered and displayed. The Last Name field is unfiltered but not used in output.

Backend Source Code
if(isset($_GET["fname"]) && isset($_GET["lname"])){
    $re = str_replace('<', ';', $_GET['fname']);
    echo $re;
}
Test Input Form
This field replaces '<' with ';'
This field has no filters but is not displayed in output
Character Filter Bypass Techniques
  • Alternative syntax: Try using other ways to execute JavaScript without using '<'
  • Event handlers in existing elements: If there are other elements on the page, try adding event handlers to them
  • JavaScript URLs: Use javascript:alert(1) in href or other attributes if you can create links
  • CSS expressions: In older IE browsers, CSS expressions can execute JavaScript
  • Unicode/encoding: Try using Unicode characters that represent '<' but might not be filtered
  • Nested contexts: If the output appears in a JavaScript context, you might not need HTML tags at all
  • Template literals: In modern JavaScript contexts, template literals might help
  • Alternative protocols: data: URIs or other protocols might bypass the filter
Security Analysis

This character replacement filter demonstrates:

  • Single-character filters are easily bypassed
  • Context-aware filtering is necessary for proper protection
  • Output encoding should happen at the rendering stage, not input stage
  • Character filters often break legitimate content while being insufficient for security
  • Multiple encoding layers or context-specific escaping is required
Proper Defense Strategies

For effective XSS prevention:

  • Use context-aware output encoding (HTML, JavaScript, URL contexts)
  • Implement Content Security Policy (CSP) headers
  • Validate input using whitelists, not blacklists
  • Use proven sanitization libraries like DOMPurify
  • Employ proper HTTP headers (X-XSS-Protection, X-Content-Type)
  • Never rely on simple character replacement for security
About Character-Level Filtering

Character replacement filters are one of the weakest forms of XSS protection because:

  • They only address specific characters, not attack patterns
  • Attackers can easily encode or obfuscate the filtered characters
  • They often break legitimate user input containing those characters
  • Different contexts (HTML, JavaScript, CSS) require different escaping
  • Modern browsers have complex parsing that can bypass simple filters

This lab shows why character-level filtering should never be the primary defense against XSS attacks.