Offensive Security

Introduction to Cross-Site Scripting (XSS)

Jul, 23rd 2023

This article presents a great introduction for anyone trying to learn about Cross-Site Scripting (or XSS). You don’t need to be an expert to follow along. However, you do need to know some basics about how the web works in order to gain the most from this article.

We will start first by learning about what Cross-Site Scripting is and what are its types. Then, we will explore the process of conducting an XSS attack. And finally, we will list some of the good practices that we can follow to prevent it.

Disclaimer: Please note that the information taught in this article is not intended to be used for anything other than legitimate and ethical purposes. As with all my other articles, the objective here is to further expand the security culture and to help defend and protect information systems against malicious actors.

So, with that being said, let’s begin!

What is Cross-Site Scripting (XSS)?

Cross-Site Scripting (XSS) is a type of vulnerability that affects web applications. It allows an attacker to send malicious code to a website. That same code is then sent to other users to be executed on their browsers.

When successful, an XSS attack can provide the attacker with sensitive information from other users’ browsers. For instance, the attacker can retrieve user cookies and session tokens, which they can then use to perform session hijacking.

Here is an illustration that should help you better understand the process of the attack.

Considering that end-users are generally trusting of the vulnerable website, they will be unsuspecting of the attack if it ever happens against them.

XSS Types

There are two main types of Cross-Site Scripting attacks: Persistent and reflected.

Persistent XSS

persistent (Also called stored) XSS attack is the most dangerous of the two types. It occurs when the malicious script provided by the attacker is stored on the server-side of the web application. This code is then sent to other users every time they request the content associated with it.

For example, a comment section is one place where persistent XSS can occur. This is because websites store comments in a database on the server-side, and they retrieve and display them every time a user visits that section.

The above illustration is an example of a persistent XSS attack.

Reflected XSS

reflected XSS attack is the least dangerous of the two types. In a reflected XSS scenario, the malicious script is sent to the web application and then presented to the user that submitted the request, and only to that user. The website doesn’t store anything on the server side.

A good example of where a reflected XSS attack can happen is a search form. Since only the user who provides a string in a search form can see that string in the response, an attacker won’t be able to perform a persistent XSS attack. The worst they can do is to conduct a reflected XSS attack.

This might not seem dangerous at first, but if a malicious actor combines it with a phishing attack, they can use it to retrieve sensitive information from other users.

How to perform a Cross-Site Scripting Attack

Now that we know what a Cross-Site Scripting attack is, let’s see how we can perform one.

First of all, we need to determine if our target website is vulnerable to XSS. To do so, we need to consider all points on the website where a user can provide input.

For each point, we can run a proof of concept payload that will confirm whether or not we have an XSS vulnerability. Most often, we can use the “alert()” Javascript function inside a script.


If the website is vulnerable to XSS, then an alert message should pop up with the “XSS!” message. This is all the proof that we need to confirm the vulnerability of our target.

You should note that most websites may detect and block the above payload. This does not mean that these websites aren’t vulnerable, it just means that you need to obfuscate the payload to evade detection.

Once we’ve determined the vulnerability of the website, you can run a payload that will send the user’s cookie to a webpage that you control.

document.write('<img src="'+document.cookie()+'" \>');

The above payload will attempt to load an image from a website controlled by the attacker. The link of the image contains the cookie value of the target user. So, when it receives this request, the malicious website will log this value.

The attacker can then check the logs to retrieve the cookies of all users who connected to that website.

Protect against XSS

Here are some good practices that you should follow to protect your website against XSS attacks:

  • The web application should always validate user input, and that is, for every data provided by users. This process involves ensuring that the provided input is in the expected format. For example, if you are asking the user for their age on an input field, then you should expect the provided data to be a positive integer that is less than 120. Any value that is outside of this range shouldn’t be accepted.
  • Web applications can also use encoding to escape certain characters that aren’t supposed to be processed by the web browser. For example, if we want to embed user-provided input into an HTML element, we would need to HTML-encode it. That is, we need to convert HTML reserved characters into HTML entities (For example, ‘<‘ will be converted to ‘<’). Likewise, if we want to embed user-provided input into a Javascript data value, we would need to Javascript-encode it.
  • The HTTP Header can also provide a good layer of defense against XSS. The use of “Content-Type” and “X-Content-Type-Options” in response headers can limit the execution of scripts on a webpage.

We have covered the essentials in this article. So now, you should have a basic understanding of Cross-Site Scripting.

Nevertheless, there is more to XSS than what we have covered here. So you shouldn’t be content. At least not yet. I invite you to build on what we have discussed here and learn from other resources on the web. For instance, the OWASP and PortSwigger websites provide a good reference for this topic.



No comments