Reflected/non-persistent cross-site scripting

What is reflected/non-persistent cross-site scripting?

Reflected cross-site scripting is a type of cross-site scripting (XSS) where the attacker does not send the payload to the web application; instead, they send it to the victim in the form of a URL that includes the payload (often obfuscated). The victim clicks the URL and opens the vulnerable web application, unwittingly executing the payload. Reflected cross-site scripting is also called non-persistent cross-site scripting.

Example of reflected/non-persistent cross-site scripting

In this example, the developer wants to display the name of the currently authenticated user on a welcome screen (welcome.php). They include the following login form on the login.php web page:

<form action="/welcome.php" method="get" id="login">
  <label for="name">Your name:</label>
  <input type="text" id="name" name="name">
  <label for "password">Your password:</label>
  <input type="password" id="password" name="password">
  <button type="submit" form="login" value="login">Log in</button>
</form>

The welcome.php file includes the following code:

// Display the name of the user
(...)
$name=$_GET["name"];
echo "<strong>Hello, ".$name."!</strong>";
(...)

As you can see, the application sends the name and password using the GET method and then displays the name on the welcome.php page without any validation or sanitization.

The reflected cross-site scripting attack

The attacker creates the following URL:

http://www.example.com/welcome.php?name=
%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28
%22%4c%45%41%56%45%20%54%48%49%53%20%50%41
%47%45%21%20%59%4f%55%20%41%52%45%20%42%45
%49%4e%47%20%48%41%43%4b%45%44%21%22%29%3b
%3c%2f%73%63%72%69%70%74%3e

The long string of hex codes in this payload is a URL-encoded form of the following content:

<script>alert("LEAVE THIS PAGE! YOU ARE BEING HACKED!");</script>

Then, the attacker sends the URL to the victim, for example, in an email or instant message. The victim clicks the URL, opens the welcome.php page, and their browser interprets the following code:

<strong>Hello, <script>alert("LEAVE THIS PAGE! YOU ARE BEING HACKED!");</script>!</strong>

The browser finds a <script> tag and executes the JavaScript code within it. As a result, it displays a pop-up window urging the user to leave the page. The consequences are that targeted users will stop visiting the web application, fearing for their safety.

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 welcome.php file in the following way:

// Display the name of the user
// Use HTMLPurifier with HTML escaping to avoid XSS
$name=$_GET["name"];
// Purify user data using HTMLPurifier
(...)
$purifier = new HTMLPurifier($config);
$purified_name = $purifier->purify($name);
// Just to be sure, HTML-escape special characters
$safe_name = htmlspecialchars($purified_name, ENT_QUOTES);
// Display the safe name
echo "<strong>Hello, ".$safe_name."!</strong>";
(...)

Consequences of reflected/non-persistent cross-site scripting attacks

Reflected cross-site scripting is regarded as less dangerous than stored/persistent XSS, but the consequences can also be dire. A reflected XSS attack is more difficult to perform because it needs more than just creating and delivering a single payload. The attacker also needs to use social engineering techniques to target a specific victim or group of victims.

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

  • They could create a phishing campaign and send millions of emails containing a malicious link with a payload that redirects users to a phishing page designed to mimic your web application. As a result, millions of users could potentially have their credentials stolen and blame your web application, which would severely damage your reputation.
  • They could create a payload that sends the user to a malicious page that imitates your application’s login page. Then, they could send this malicious URL to your internal users, even your CEO. If even one of your users falls for the trick, the attacker will obtain their credentials to escalate the attack. Ultimately, this could let malicious actors gain access to other computer systems in your organization.

How to prevent reflected/non-persistent cross-site scripting vulnerabilities

To prevent reflected/non-persistent 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 reflected cross-site scripting?

In a reflected cross-site scripting attack, the attacker does not send the attack payload directly to the web application. Instead, they send it to the victim in the form of a URL that includes the payload. The victim clicks the URL and opens the vulnerable web application, causing their browser to execute the payload.

 

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

How is reflected cross-site scripting used by attackers?

Reflected cross-site scripting is the most common type of vulnerability used in conjunction with phishing attacks. Phishers use the authority of domain names to make their malicious links look more legitimate to victims. Phishing often helps attackers with the distribution of ransomware.

 

Find out how cross-site scripting, phishing, and ransomware are all connected.

How to prevent reflected 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.

Related blog posts


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