Learn Pentesting: A Deep Dive into Manual Cross-Site Scripting (XSS) Testing

Welcome to this installment of the Learn Pentesting series by Numorian. In this post, we will explore manual testing techniques for identifying Cross-Site Scripting (XSS) vulnerabilities during web application penetration tests. This deep-dive is intended for highly technical audiences—penetration testers or security professionals who want a comprehensive reference for manual XSS testing.


1. Understanding Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) is a vulnerability that allows attackers to inject malicious scripts into web pages viewed by other users. There are three primary types of XSS:

A robust understanding of these types is crucial, as each requires a different testing approach and exploitation technique.


2. Manual Testing Techniques for XSS

Manual testing is a fundamental skill for identifying XSS vulnerabilities that automated tools might miss. Here’s how to perform a systematic test:

2.1 Identifying Input Vectors

Begin by identifying all points where user input is accepted and subsequently reflected in the application output. Common input vectors include:

2.2 Initial Payload Testing

A simple yet effective test payload is:

<script>alert('XSS');</script>

Insert this payload into various input vectors and observe if the script is executed. For example, if you have a search page:

https://example.com/search?q=<script>alert('XSS');</script>

Check the rendered HTML using your browser’s developer tools (Inspect Element) to verify if the script tag is present and executed.

2.3 Testing in Different Contexts

Different contexts in a web page require different payloads. For example:


3. Crafting Payloads and Evasion Techniques

When testing manually, the goal is to identify not only the obvious injection points but also bypass common filters. Consider the following techniques:

3.1 Encoding and Obfuscation

Filters may block common keywords (like <script>), so try alternative representations:

3.2 Using Event Handlers

Event handlers in HTML tags can serve as alternative vectors:

<img src="nonexistent.jpg" onerror="alert('XSS')">

3.3 Breaking Out of Context

If the application sanitizes quotes or specific characters, test payloads that break out of the current context. For instance, if the user input is embedded inside a JavaScript string:

'); alert('XSS');//

This technique closes the existing string and injects a new JavaScript command.


4. Practical Example: Testing for Reflected XSS

Let’s walk through a practical example for a reflected XSS test.

4.1 The Scenario

Imagine a simple search form on a web application:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Search Page</title>
</head>
<body>
  <form method="GET" action="/search">
    <input type="text" name="q" placeholder="Search...">
    <input type="submit" value="Go">
  </form>
  <div>
    <!-- The search query is echoed back unsanitized -->
    You searched for: <?php echo $_GET['q']; ?>
  </div>
</body>
</html>

4.2 Injecting the Payload

  1. Identify the Input:
    The q parameter is reflected back to the page.

  2. Insert a Basic Payload:
    Use the following URL:

    https://example.com/search?q=<script>alert('XSS');</script>
    
  3. Observation:
    If the payload is executed, the browser will display an alert box. Use browser developer tools to verify if the payload appears in the HTML output.

  4. Refine the Test:
    If the initial test does not work, modify the payload for context. For instance, try:

    "><script>alert('XSS')</script>
    

    This payload attempts to break out of any attribute context and directly insert the script tag.


5. Leveraging Developer Tools

Modern browsers provide powerful tools that are indispensable during manual testing:


6. Best Practices for Manual XSS Testing

6.1 Always Validate Context

Before crafting your payload, understand the context in which the input is reflected:

6.2 Use Incremental Payloads

Start with simple payloads and then escalate complexity as needed. This helps in isolating which filters are applied and where they might be bypassed.

6.3 Document Your Findings

Take screenshots and document the payloads that trigger XSS. This documentation will be crucial when communicating findings with development teams or preparing remediation strategies.

6.4 Stay Up-to-Date

XSS testing techniques evolve over time. Regularly review the latest research and payload repositories (like the XSS Cheat Sheet) to stay ahead of emerging bypass techniques.


7. Conclusion

Manual testing for Cross-Site Scripting (XSS) is both an art and a science. While automated tools are helpful, they often miss nuances that manual testing can reveal. By understanding the context, leveraging developer tools, and crafting clever payloads, penetration testers can uncover XSS vulnerabilities that might otherwise remain hidden.

This article has provided a technical deep-dive into manual XSS testing techniques—complete with practical examples and code snippets. As part of the Learn Pentesting series, we hope this serves as a valuable reference in your security testing toolkit. Keep experimenting, documenting, and refining your approach to stay effective in the ever-evolving landscape of web application security.

Happy testing!

Ready to see how Numorian can help your business?

Contact us today to learn more about our services and how we can support your business.