How to Detect Blind XSS Vulnerabilities

Non-Persistent vs Persistent XSS Vulnerabilities

Cross-site scripting (XSS) vulnerabilities are one of the Top 10 web vulnerabilities according to OWASP. They can be classified into two types:

  • Non-persistent (or reflected) Cross-site Scripting vulnerabilities occur when the client-side user input is reflected immediately by the web browser on the page by server-side scripts without proper sanitization. Reflected XSS vulnerabilities are the most common type.
  • Persistent (or stored) Cross-site Scripting vulnerabilities occur when user input provided by the attacker is saved by the web server and then permanently displayed on pages returned to other users in the course of regular browsing, without proper HTML escaping. Stored cross-site scripting attacks are much more dangerous compared with the reflected XSS because the attacker payload remains on the vulnerable page and any user that visits this page will be exploited. A persistent XSS vulnerability can be transformed into an XSS worm (like it happened with the Samy XSS worm that affected Myspace several years ago).

Overview of Blind Cross-site Scripting

Blind XSS vulnerabilities are a variant of persistent XSS vulnerabilities. They occur when the attacker input is saved by the web server and executed as a malicious script in another part of the application or in another application. For example, an attacker injects a malicious payload into a contact/feedback page and when the administrator of the application is reviewing the feedback entries the attacker’s payload will be loaded. The attacker input can be executed in a completely different application (for example an internal application where the administrator reviews the access logs or the application exceptions).

Example of web applications and web pages where blind XSS attacks can occur:

  • Contact/Feedback pages
  • Log viewers
  • Exception handlers
  • Chat applications / forums
  • Customer ticket applications
  • Web Application Firewalls
  • Any application that requires user moderation

These types of vulnerabilities are much harder to detect compared to other reflected XSS vulnerabilities where the input is reflected immediately. In the case of blind XSS, the attacker’s input can be saved by the server and only executed after a long period of time when the administrator visits the vulnerable dashboard page. It can take hours, days, or even weeks until the payload is executed. Therefore, this type of vulnerabilities in web applications cannot be tested as other types of XSS vulnerabilities and they pose a challenge for web security (web application security), penetration testing, and security testing in general.

Detecting Blind Cross-site Scripting Vulnerabilities with AcuMonitor

Acunetix Web Vulnerability Scanner has a service named AcuMonitor, which was designed to detect this type of vulnerabilities (and other new categories of web application vulnerabilities that could not be detected before).

The AcuMonitor service allows you to detect blind XSS vulnerabilities as described below:

  1. User registers to the AcuMonitor service by providing an email address for notifications.
  2. Acunetix injects various script payloads into the tested web application (into GET/POST variables, HTTP headers, cookies, URLs, etc.)
  3. If the web application is vulnerable to blind XSS, the script payload is saved into the database.
  4. When the web application administrator visits the vulnerable page, the previously injected script payload is executed. This script will be loaded from an AcuMonitor server that gathers basic information about the vulnerable page.
  5. AcuMonitor sends a notification email to the registered user. The notification email contains the information gathered about the vulnerable page and information about the HTTP request that injected the script payload.
  6. The user can use the information in the notification email to look up the original request from Acunetix.

Detecting a Real-Life Blind XSS Vulnerability in a WordPress Plugin

The Count per Day WordPress plugin was vulnerable to a Blind XSS vulnerability that was fixed in version 3.2.6. The vulnerability occurred because the script counter.php was not properly sanitizing the HTTP Referrer header. This plugin was saving the last user referrers to the database and displaying this information on the WordPress Dashboard plugin page. To exploit this vulnerability, an attacker would need to send a web request to any page with a custom HTTP Referrer header and wait for the administrator to visit the WordPress Dashboard page. At this point, the attacker could steal WordPress cookies or perform other attacks.

After the vulnerable web application was scanned with Acunetix (with the AcuMonitor service enabled), we logged into the WordPress Dashboard page. Various script payloads were injected into the application during scanning. At this point, the injected script payloads were executed and AcuMonitor started to get information about the vulnerable page and prepared a notification for the user. In a few minutes, the user received a notification email about the blind XSS vulnerability with information on how to reproduce this vulnerability.

The XSS detection email contained the following details:

Blind XSS email notification from the AcuMonitor Service.

Blind XSS email notification from the AcuMonitor Service. (Click to enlarge)


AcuMonitor extracted various information, which could be used by the user to reproduce the vulnerability.

The alert details included the IP address, user-agent, page URL, page title, the Referrer header and the cookies used when visiting the vulnerable page. Also, a screenshot was generated by the injected malicious code.

The alert also contained an attachment that, when opened, loads the HTTP request that injected the malicious JavaScript code. The initial HTTP request can also be loaded using the Request ID information in the AcuMonitor settings page.

Blind XSS initial HTTP Request through AcuMonitor Service, Acunetix

Blind XSS initial HTTP Request. (Click to enlarge)


From the initial HTTP request, the user can easily identify that the injection vector is the Referrer header, and can use this information to fix the vulnerability (or in this case contact the WordPress plugin developers).