Blog | G5 Cyber Security

XSS: Bypassing Frontend Encoding

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

  1. 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.
  2. 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).
  3. 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.
  4. Double Encoding: If the server encodes ampersands *again* after receiving input, you can use double encoding.
    • Inject &lt;script>alert(1)&lt;/script>.
    • The frontend will encode it as &amp;lt;script>alert(1)&amp;lt;/script>.
    • When the server decodes it, it becomes <script>alert(1)</script> which is then rendered as executable code.
  5. 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.
  6. 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>.

Exit mobile version