Blind cross-site scripting

What is blind cross-site scripting?

Blind cross-site scripting is a sub-type of stored/persistent cross-site scripting where the web application stores the payload sent by an attacker and only executes it later – at a different time or in a different place, possibly even in another web application.

Example of blind cross-site scripting

In this example, the developer allows the user to register in the web application by choosing an arbitrary username. The register.php page of the application includes the following form:

<form action="/registered.php" method="post" id="comment">
  <label for="username">Choose a username:</label>
  <input type="text" id="username" name="username">
  <label for "password">Choose a password:</label>
  <input type="password" id="password" name="password">
  <button type="submit" form="register" value="register">Register</button>
</form>

The registered.php file includes the following code:

// Add the new user to the database using PDO to avoid SQL injection
(...)
$username=$_POST["username"];
$password=password_hash($_POST["password"], PASSWORD_DEFAULT);
$sql = "INSERT INTO users (username, password) VALUES (?,?)";
$statement = $pdo->prepare($sql);
$statement->execute([$username, $password]);
(...)

As you can see, the application inserts the username into the database without any validation or sanitization.

At the same time, another developer creates a different application that allows an authenticated administrator to display a list of the 50 newest users. The newusers.php page displays them in a table:

(...)
$sql = "SELECT * FROM users ORDER BY id DESC LIMIT 50";
$statement = $pdo->query($sql);
while ($row = $statement->fetch()) {
    echo "<tr><td>".$row['id']."</td><td>".$row['username']."</td></tr>";
}
(...)

As you can see, this application assumes that the data in the database is safe and does not perform any validation or sanitization before displaying it.

The blind cross-site scripting attack

The attacker enters the following username into the form:

<script>alert("YOUR ADMINISTRATIVE INTERFACE IS HACKED!");</script>

After the attacker clicks the Register button, this attack payload is saved in the database as a new username.

A week later, an administrator opens the administrative application and calls the function (newusers.php page) that lists the latest 50 users that registered via the public application. If the malicious user is among them, the browser receives and interprets the following code when it encounters the malicious username:

<td><script>alert("YOUR ADMINISTRATIVE INTERFACE IS HACKED!");</script></td>

The browser finds a <script> tag and executes the JavaScript code within it. As a result, it displays a pop-up window for the administrator.

The fix

Informed of the vulnerability, the developer decides to use HTMLPurifier filtering to safeguard the code and, additionally, escape HTML characters. They import the HTMLPurifier library and modify the registered.php file in the following way:

// Add a new comment into the database using PDO to avoid SQL injection
// and HTMLPurifier with HTML escaping to avoid XSS
(...)
$username=$_POST["username"];
$password=password_hash($_POST["password"], PASSWORD_DEFAULT);
// Purify user data using HTMLPurifier
(...)
$purifier = new HTMLPurifier($config);
$purified_username = $purifier->purify($username);
// Just to be sure, HTML-escape special characters
$safe_username = htmlspecialchars($purified_username, ENT_QUOTES);
// Save safe data in the database
$sql = "INSERT INTO users (username, password) VALUES (?,?)";
$statement = $pdo->prepare($sql);
$statement->execute([$safe_username, $password]);
(...)

Consequences of blind cross-site scripting attacks

Blind cross-site scripting is just as dangerous as other variants of stored XSS – if not more, since its impact is not immediate and detection is more difficult. A successful attack may have any of the consequences listed in the general section dedicated to cross-site scripting.

Here are some actions that a black-hat hacker could perform only based on the simple example presented earlier:

  • They could redirect the administrator to a malicious page that mimics the original application and ask them to log in, thus stealing their credentials.
  • They could steal the administrator’s session cookies to impersonate a privileged user.
  • They could trick the administrator into downloading and installing malware on their computer, for example, a trojan, cryptocurrency miner, or ransomware.

Any of these attacks could let the attacker escalate and possibly gain access to other computer systems in your organization.

How to detect blind cross-site scripting vulnerabilities

Blind XSS vulnerabilities are much more difficult to detect than other types of XSS flaws. To detect them using automated tools, you need a security testing tool (scanner) that can detect blind/out-of-band vulnerabilities using a dedicated external service. Examples of such tools are Invicti and Acunetix by Invicti. Simple web vulnerability scanners that only analyze direct responses from the application are unable to detect blind/out-of-band vulnerabilities.

How to prevent blind cross-site scripting vulnerabilities

To prevent blind cross-site scripting, follow our overall guidelines for preventing cross-site scripting, listed in the general section dedicated to cross-site scripting.

Frequently asked questions

What is blind cross-site scripting?

Blind cross-site scripting is similar to stored cross-site scripting, but in a blind XSS attack, the web application stores the payload sent by an attacker and only executes it later – at a different time, in a different place, or possibly even in another web application.

 

Learn what is stored cross-site scripting.

How to detect blind cross-site scripting?

Blind cross-site scripting is very difficult to detect because it can span more than one application. The tools used to scan your web applications must be advanced enough to recognize attacks that are initiated from one application but affect another.

 

Read more about cross-site scripting (XSS) in general.

How to prevent blind cross-site scripting?

The best way to avoid cross-site scripting vulnerabilities is through validation and sanitization of user input. There are two primary techniques that you can use to sanitize data coming from the user: filtering and escaping.

 

Find out about the potential consequences of cross-site scripting attacks.


Written by: Tomasz Andrzej Nidecki, reviewed by: Benjamin Daniel Mussler