Simplifying XSS Detection with Nuclei - A New Approach

Introducing next level XSS detection with Nuclei.

XSS (Cross-Site Scripting) detection has long been a challenge, balancing accuracy with avoiding excessive false positives. Traditionally, this meant creating specific reflection based string matchers for each target, leading to complex and hard-to-maintain configurations. But with headless modes, we can simplify and improve XSS detection in a more intuitive and efficient way.

In this post, we'll explore how to leverage nuclei headless mode to detect XSS payloads more easily and accurately, using the waitdialog action. This approach significantly reduces the complexity of matching specific server responses, while maintaining high accuracy.

The Challenge of XSS Detection

For those who've worked with XSS detection templates, the complexity of configuring specific matchers for every scenario is all too familiar. It becomes especially cumbersome when analyzing unique technologies or servers. Often, security engineers have to conduct additional research, using tools like Shodan or setting up vulnerable environments to fine-tune their matchers. While this approach improves accuracy and reduces false positives, it places a heavy burden on the user.

For example, look at the following template snippet:

matchers-condition: and
matchers:
  - type: word
    part: body
    words:
      - 'topic_id: "</script><script>alert(document.domain)</script>'
      - "window.erxesEnv"
    condition: and

In this method, specific keywords in the response body are used to check if the injected script is reflected (although this doesn’t guarantee that the payload will actually be triggered). This approach requires detailed knowledge of the target's structure and can easily fail if the structure changes - even a little.

Enter Headless Mode

Nuclei's headless mode lets us mimic real user actions on a web page, including running JavaScript. This opens up a new way to detect XSS: instead of just looking for specific HTML output or script tags, we can check if an XSS payload actually triggers a JavaScript dialog (like alert).

The waitdialog action listens for these dialogs on a page, showing us clearly if an XSS payload has been executed. This method simplifies detection by focusing on the behavior of the payload rather than the page's source code.

Implementing Headless XSS Detection

Let's take a look at how we can implement this in practice.

The Old Way: Matcher-Based Detection

Before headless mode, detecting XSS relied heavily on matchers, as seen below:

id: CVE-2021-32853

# ... SNIPPED ...

http:
  - method: GET
    path:
      - "{{BaseURL}}/widgets/knowledgebase?topicId=%3C%2Fscript%3E%3Cscript%3Ealert%283%2B4%29%3C%2Fscript%3E"

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - 'topic_id: "</script><script>alert(3+4)</script>'
          - "window.erxesEnv"
        condition: and

      - type: word
        part: header
        words:
          - text/html

      - type: status
        status:
          - 200

In this older method, you had to define the HTTP headers and exact patterns to match the payload. While it works, the setup is more complicated because you need to create separate matchers for each different environment.

The New Way: Headless Dialog Detection

With headless mode, we can simplify this process by detecting the JavaScript execution directly:

id: CVE-2021-32853

# ... SNIPPED ...

headless:
  - steps:
      - args:
          url: "{{BaseURL}}/widgets/knowledgebase?topicId=%3C%2Fscript%3E%3Cscript%3Ealert%283%2B4%29%3C%2Fscript%3E"
        action: navigate

      - action: waitdialog
        name: reflected_topicId_query

    matchers:
      - type: dsl
        dsl:
          - reflected_topicId_query == true
          - reflected_topicId_query_message == "7" # 3+4
        condition: and

Here, instead of searching for specific HTML content or headers, we use the waitdialog action to wait for a JavaScript dialog to pop up. If the dialog gets triggered, the matcher checks if it matches the expected result (like alert(3+4)).

💡
The waitdialog action has been available since Nuclei v3.3.2 (bump now!), and you can refer to the documentation for more details on its usage.
$ nuclei -t headless-xss.yaml -target https://erxes.xss -headless

                     __     _
   ____  __  _______/ /__  (_)
  / __ \/ / / / ___/ / _ \/ /
 / / / / /_/ / /__/ /  __/ /
/_/ /_/\__,_/\___/_/\___/_/   v3.3.2

		projectdiscovery.io

[INF] Current nuclei version: v3.3.2 (latest)
[INF] Current nuclei-templates version: v9.9.4 (latest)
[WRN] Scan results upload to cloud is disabled.
[INF] New templates added in latest release: 59
[INF] Templates loaded for current scan: 1
[WRN] Loading 1 unsigned templates for scan. Use with caution.
[INF] Targets loaded for current scan: 1
[CVE-2021-32853] [headless] [critical] https://erxes.xss/widgets/knowledgebase?topicId=%3C%2Fscript%3E%3Cscript%3Ealert%283%2B4%29%3C%2Fscript%3E
💡
To run headless based Nuclei templates, use the -headless option (disabled by default).

Benefits of Headless Detection

  1. Higher Accuracy: It listens for real script execution, so you get better results with fewer false positives.
  2. Reduced Complexity: No need to create detailed matchers for each server or target. Instead, it focuses on how the payload behaves, not just the response structure.
  3. Consistency: Whether you're dealing with a simple website or a complex application, headless mode provides consistent XSS detection every time.

Wrapping Up

Integrating headless mode into XSS detection is a game-changer, making things easier and more accurate. With the waitdialog action, we can skip the headaches of traditional reflection based detection. No more tweaking detection for every server or technology—just straightforward, reliable XSS detection.

By combining headless mode with dialog handling, users can create simpler detection templates that focus on how XSS payloads behave. This approach cuts down the complexity and boosts reliability.

Headless mode is the future of XSS detection, and this approach brings us one step closer to making it easier for everyone.

References


You can also join our Discord server. It's a great place to connect with fellow contributors and stay updated with the latest developments. Thank you, once again!

By leveraging Nuclei and actively engaging with the open-source community, or by becoming a part of the ProjectDiscovery Cloud Platform, companies can enhance their security measures, proactively address emerging threats, and establish a more secure digital landscape. Security represents a shared endeavor, and by collaborating, we can consistently adapt and confront the ever-evolving challenges posed by cyber threats.

Subscribe to our newsletter and stay updated.

Don't miss anything. Get all the latest posts delivered straight to your inbox. It's free!
Great! Check your inbox and click the link to confirm your subscription.
Error! Please enter a valid email address!
--