TL;DR
Many websites encode ampersands (&) in user input to prevent basic XSS attacks. However, this encoding is often only applied on the frontend for display purposes and isn’t a robust security measure. This guide shows how to bypass this frontend encoding by injecting payloads that are decoded before rendering or using techniques like double encoding.
Steps
- Understand the Problem: Websites often encode ampersands (&) in user input to prevent HTML entities from being interpreted as code. This is a common frontend defense, but it’s usually not enough on its own.
- Frontend encoding only affects how the data *looks* when displayed.
- The server might still receive and process the raw, unencoded input.
- Test for Frontend-Only Encoding: Try a simple XSS payload like
<script>alert(1)</script>.- If the alert box pops up, the encoding is likely only happening on the frontend.
- If it doesn’t, investigate further (see step 4).
- Bypass with Raw Encoding: If the server receives raw input, you can directly inject XSS payloads.
- Try injecting
<script>alert(1)</script>. The server might not re-encode it before rendering.
- Try injecting
- Double Encoding: If the server encodes ampersands *again* after receiving input, you can use double encoding.
- Inject
<script>alert(1)</script>. - The frontend will encode it as
&lt;script>alert(1)&lt;/script>. - When the server decodes it, it becomes
<script>alert(1)</script>which is then rendered as executable code.
- Inject
- Payload Variations: Experiment with different payloads to find one that works.
- Try using event handlers like
<img src=x onerror=alert(1)>. - Consider using HTML injection techniques if XSS isn’t directly possible.
- Try using event handlers like
- Context Awareness: Pay attention to where your input is being placed in the HTML.
- If it’s inside an attribute, you might need to use different encoding strategies (e.g., single quotes instead of double quotes).
Example Scenario
Imagine a website that displays user comments. The frontend encodes ampersands in the comment text.
// Frontend JavaScript (example)
function displayComment(comment) {
const encodedComment = comment.replace(/&/g, '&');
document.getElementById('comment-container').innerHTML += encodedComment;
}
If the server doesn’t re-encode the comment before storing it in the database, you can bypass the frontend encoding by injecting a payload like <script>alert(1)</script>.

