Cross-site Scripting (XSS)
Jscrambler
Posted on July 12, 2022
Cross-site scripting is a vulnerability that happens when there’s an injection of malicious code to run on a regular webpage. This piece of code can go on to cause unauthorized actions and access data. Many times, these attacks seem to be a legitimate part of the website because they are added as parameters on the original URL.
We’ll be covering different types of these attacks and how modern frontend frameworks help handle XSS attacks.
Types Of XSS Attacks
Cross-site scripting attacks come in different forms in a bid to steal user data and information.
The main idea is to use any input medium to send malicious code to the application. These types are reflected, Stored, and DOM-based attacks.
Reflected XSS Attacks
This is the most common type of attack where the attackers create a malicious link using the website and adds the malicious code as URL param.
https://webapp.com/?keyword=<script>alert("You've been hacked")</script>
The attacker takes the compromised URL and sends it to a specific user or a number of users through phishing emails. Unsuspecting users click on the link in the mail and open it in their browser. The code in the parameter runs on the website and executes whatever malicious intent the attacker wants.
Interestingly, Chrome now checks for URLs with script tags like what we have above. It detects it as an XSS attack and counters it. So attackers now try to shorten the links using link shorteners, that way, the param are not explicitly displayed as part of the link. Or, they encode the param in base 64 or whatever format that does not display the script tag and inner code.
Stored XSS Attacks
This type of attack takes a different approach. The attack is initiated from inside the website itself. It simply sends a piece of javascript code to the database using a regular input tag. The attacker goes to the website and looks for any input that can send data to the server like comment sections, search bar, or even forms. Then, instead of sending a regular text the attackers sends malicious code inside a script tag.
<script>alert("you've been hacked")</script>
We then store the piece of code in the database. Whenever we call the data on the client-side, the piece of code is returned and runs, rather than just displaying it. For instance, the hacker can use this to get the user’s credentials in the local storage or cookies and send it to their own servers, thus compromising users' data.
DOM-Based XSS Attacks
Similar to the reflected XSS attacks, this can be initiated using parameters in the URL. In this case, the script tag will contain a function that uses the DOM to get HTML elements on the webpage and manipulate the webpage by running their own script. Let’s take a look at this code below:
window.onload = function () {var searchResult = document.getElementById('searchResult');searchResult.innerHTML = `You've been hacked` + searchResult;}
We get the text whose id is searchResult and replace it with a malicious text on load. This is added to the DOM using innerHTML.
Now, to add this code to the webpage we will need to add it as a query param.
https://webapp.com/?keyword=<script>window.onload = function () {var searchResult = document.getElementById('searchResult');searchResult.innerHTML = `You've been hacked` + searchResult;}</script>
As explained earlier, the attacker finds a way to send this malicious link to unsuspecting victims who unknowingly run the code and get hacked.
How Current Single Page Application (SPAs) Handle XSS Attacks
As the web evolves, Single Page Applications (SPAs) were created to abstract a lot of complicated things on the frontend which greatly improves the developer experience. These things include data management, state, reusability of UI components, security, etc. For instance, React helps handle XSS attacks by escaping all variables that is displayed to the user.
const Component = () => {
return (
<h1> Hello {hackString}!</h1>
)
}
What this means is by design attackers can’t inject code that can override existing text on the webpage.
For instance, if the attacker tries to inject code in a script tag like this:
var hackString = '<script>alert("YOU ARE HACKED")</script>';
If you try to display this string as a text in our react component, React escapes it and and displays it as a plain string.
return (
<div>{hackString}</div>
);
The only way the attacker can find a way around it is if we use dangerouslySetInnerHTML to add text to our react component, which is something React advises against because of the XSS risk.
return (
<div dangerouslySetInnerHTML={{"__html": hackString}} />
);
Vue
Vue also handles XSS attacks well. It escapes all HTML content, meaning similar to React, external code cannot be injected into any component in our application.
Assuming the attacker tries to inject hackString into our Vue app:
<h1>{{ hackString }}</h1>
Vue escapes the Javascript code to display the following HTML:
<script>alert("hackString")</script>
The only case where we can create XSS attack vulnerability in our application is if we use v-html. That’s because v-html` uses the DOM to add content directly to our website.
`
`
Conclusion
This article covered cross-site scripting and how it can affect websites. We talked about types of XSS attacks and how they present themselves differently. These attacks are caused by user-generated data and so the solution is to be able to filter the data before sending them to the server and vice-versa.
Also, we looked into modern frontend frameworks and how they secure the apps against attacks. This is done by escaping data that is not text, meaning strings containing code can be escaped instead of allowing the browser to run it as actual code. As you build, one thing to keep in mind is that XSS attacks come in different ways, and we should consider the security of our apps.
Posted on July 12, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.