A Methodology for Web Application Cross-Site Scripting Blog Post

A Methodology for Web Application Cross-Site Scripting

Posted on September 6, 2025 by Jack Mason


In this blog, I want to share the methodology I use when testing web applications for Cross-Site Scripting (XSS). Rather than relying on trial and error, this approach provides a structured process: starting with identifying input reflection, moving through context analysis and filter evasion, and finally progressing towards payloads that deliver meaningful impact.

What is Cross-Site Scripting?

Cross-Site Scripting (XSS) is a client-side injection vulnerability that allows attackers to execute arbitrary JavaScript in the browser of another user. This is achieved by injecting malicious code into a vulnerable application, which is then rendered back to the victim.

The impact can range from simple proof-of-concept pop-ups to severe outcomes such as session hijacking, privilege escalation, or full account compromise. Because the browser inherently trusts scripts from the application’s origin, XSS opens the door to a wide variety of downstream attacks.

Types of Cross-Site Scripting

XSS falls into three broad categories, each with its own testing considerations:

  • Reflected XSS – The payload is reflected immediately in the server’s response, typically via query strings or form inputs.
  • Stored XSS – The payload is stored by the application (for example, in a database or log) and delivered later to other users. This type often carries higher impact due to persistence.
  • DOM-based XSS – The vulnerability exists entirely in the client-side code. Here, JavaScript processes untrusted data from sources like location.search or location.hash and writes it directly into the DOM.

XSS Methodology

A structured workflow for identifying XSS can be broken down into three phases:

Phase 1: Input Reflection and Context Identification

The first task is to map out where input appears in the application.

1. Submit a Unique Marker:

For every input vector (query parameters, forms, headers), inject a harmless but unique string such as TESTXSS123.

2. Check for Server-Side Reflection (Reflected/Stored XSS):

Inspect the raw HTML of the HTTP response for the marker. If it appears, you may be dealing with Reflected or Stored XSS.

3. Check for Client-Side Reflection (DOM-based XSS):

If the marker does not appear in the raw source, inspect the live DOM with browser developer tools or Burp Suite’s DOM Invader. If it shows up there, client-side JavaScript is responsible.

4. Determine the Injection Context:

Payload design depends heavily on where the input lands:

  • Between tags: <div>TESTXSS123</div>
  • Inside an attribute: <input value="TESTXSS123">
  • Inside a script: <script>var u='TESTXSS123'</script>
  • Inside CSS: <style>color:TESTXSS123</style>

Phase 2: Filter and Sanitisation Analysis

Once reflection is confirmed, the next step is to understand how the application processes your input.

1. Probe for Filtered Characters:

Inject test strings containing special characters (<>"'&()) to see what gets blocked, stripped, or encoded.

2. Identify Encoding Type:

Analyse how the special characters are modified in the output. This tells you what kind of defence you need to bypass.

  • HTML Entity Encoding: < becomes &lt;, > becomes &gt;.
  • JavaScript Unicode Escaping: < becomes \u003c.
  • URL Encoding: < becomes %3c.

3. Test for Blocked Tags and Events:

Attempt common tags (<script>, <img>, <iframe>) and event handlers (onerror, onload). If these are filtered, you may need alternative tags or less common handlers.

Phase 3: Payload Crafting and Evasion

Armed with context and filter analysis, payloads can now be built with precision.

1. Select an Evasion Strategy:

  • If <script> is blocked, try alternative tags or brute-force options from the Burp XSS cheatsheet.
  • If event handlers like onerror are blocked, cycle through others with the Burp XSS cheatsheet.
  • If characters are blocked, apply encoding, concatenation, or obfuscation.
  • If input length is limited, shorten payloads or target other reflection points.
  • If encoding is applied, experiment with double-encoding or malformed encodings.
  • As a last resort, investigate quirks in browser parsing.

2. Craft and Test the Payload:

Tailor the payload to the injection context. For example, if inside an attribute where angle brackets are blocked, an event handler (onfocus=alert(1)) may be more effective.

3. Confirm Execution:

Proof-of-concept is typically confirmed with a simple alert() or console.log() in a real browser.

4. Progress the Exploit:

XSS is often just a foothold. True exploitation explores what can be achieved next:

  • Stealing session tokens or cookies.
  • Performing CSRF-style actions as the victim.
  • Privilege escalation via administrator sessions.
  • Injecting persistent payloads into the application.

Closing Thoughts

Cross-Site Scripting remains one of the most common and impactful web vulnerabilities. By following a structured methodology—mapping reflections, analysing sanitisation, and carefully crafting payloads—you can avoid guesswork and reliably uncover exploitable flaws.

For testers, this approach not only ensures thorough coverage but also helps demonstrate real-world impact to stakeholders. And for defenders, understanding the process is the first step towards building stronger, more resilient applications.