There are many different security vulnerabilities in web applications - some security vulnerabilities are common yet cause little to no damage if exploited by an attacker. Other security vulnerabilities are rare yet can cause severe damage if abused by attackers.
Then there’s another category of security vulnerabilities, i.e the ones that are common and dangerous like cross-site scripting. Popularly known as XSS, cross-site scripting is one of the most common security vulnerabilities found in web applications and it can cause severe damage if not mitigated in a timely manner.
Cross-site scripting (XSS) vulnerabilities continue to remain a major threat to web applications as attackers exploiting XSS attacks can gain control of the user’s account and steal personal information such as passwords, bank account numbers, credit card info, personally identifiable information (PII), social security numbers, and more.
What's worse is that victims of XSS attacks, both the user and the developer of the web application, often won’t be aware that they’re being attacked.
What Are XSS attacks?
Cross-site scripting or XSS is a web security vulnerability that allows attackers to run code in your users browsers that the attacker controls.
When this malicious code is executed in a victim’s browser, the attacker can easily gain control of their data, compromise their interaction with the web application, and perform malicious actions.
In essence, cross-site scripting (XSS) attacks are used to trick a web application into sending malicious script through the browser, and each time an end-user uses the attacked page, their browser will run malicious scripts as part of the page.
Why are XSS attacks difficult to prevent?
XSS attacks are hard to prevent because there are various vectors where an XSS attack can be used in web applications. Additionally, whereas other vulnerabilities such as OS command injection or SQL injection can be prevented by using appropriately prepared statements, cross-site scripting or XSS prevention typically requires specific output encoding wherever the untrusted data is being written back to the browse.
Types of Cross-Site Scripting Attacks
There are three types of cross-scripting attacks:
Stored XSS (Persistent XSS)
In general, stored XSS occurs when an attacker injects malicious content (often referred to as the “payload”) as user input and it is stored on the target server, such as in a message forum, comment field, visitor log, database, etc.
When the victim opens the web page in a browser, the malicious data is served to the victim’s browser like any other legitimate data, and the victim ends up executing the malicious script once it is viewed in their browser.
Reflected XSS (Non-persistent XSS)
Reflected XSS occurs when the attacker-supplied input has to be a part of the request sent to the web server. It is then immediately reflected back in such a way that the HTTP response includes the malicious data from the HTTP request.
Attackers use phishing emails, malicious links, and other techniques to trick victims into making a request to the server. The reflected XSS malicious data is then executed in the victim’s browser.
Document Object Model (DOM) Based XSS
DOM-Based XSS occurs when a malicious payload is never sent to the server i.e the entire data flow takes place in the user’s browser. In a DOM-based XSS, the source of the data exists in the DOM, the sink is also in the DOM, and the data never goes out of the browser.
This type of cross-site scripting vulnerability is difficult to detect for Web Application Firewalls (WAFs) and security teams who monitor server logs because the attack is not visible to them.
What is the Impact of Cross-Site Scripting Vulnerability?
The impact of cross-site scripting vulnerabilities can vary from one web application to another. It ranges from session hijacking to credential theft and other security vulnerabilities. By exploiting a cross-site scripting vulnerability, an attacker can impersonate a legitimate user and take over their account.
If the victim user has administrative privileges, it might lead to severe damage such as modifications in code or databases to further weaken the security of the web application, depending on the rights of the account and the web application.
Here are some of the most common impacts of cross-site scripting attacks:
Account Hijacking
Attackers often steal session cookies in the browser to hijack legitimate user accounts. This allows attackers to take over the victim's session and access any functionality or sensitive information on their behalf.
Assuming a malicious actor managed to steal the session cookies of an administrative account, the attacker can gain administrative access to the entire web application.
Credential Theft
One of the most common XSS attack vectors is to use HTML and JavaScript in order to steal user credentials. Attackers can clone the login page of the web application and then use cross-site scripting vulnerabilities to serve it to the victims.
When a victim uses the vulnerable web page and inputs their credentials, they are forwarded to a server under the attacker’s control. This way, attackers can obtain the credentials of a user in plaintext instead of hacking their session cookies, which may expire.
Data Leakage
Another powerful XSS attack vector is exfiltrating sensitive data, such as social security numbers, personally identifiable information (PII), or credit card info, and performing unauthorized operations, such as bank transactions.
Once the attacker has access to the personal or sensitive information of users, they can demand ransom payments from the organization to delete the data, or leak the information of their customers.
How Can You Prevent Cross-Site Scripting Attacks?
Now that you know more about cross-site scripting attacks and their impact, let’s take a look at how you can prevent cross-site scripting or XSS attacks.
Output Encoding
Output encoding is the primary defense against cross-site scripting vulnerabilities. It is the process of converting untrusted data into a secure form where the input is visible to the user without executing the code in the browser.
You can protect your web application from various forms of cross-site scripting by using HTML entity encoding before sending untrusted data into a browser.
Avoid Inserting Untrusted Data Except in Allowed Locations
The first rule to protect your web application from cross-site scripting attacks is to deny all untrusted data in your HTML document except if it comes under the following conditions:
• HTML Entity: If you want to insert untrusted data into the HTML body, for example, inside normal tags such as [< p >, < td >, < b >, < div >,] etc, implement some rules. While many web frameworks have an HTML escaping method for these characters, it’s not sufficient for other HTML contexts. Consider using HTML entity encoding to escape these characters so that they don’t switch into any execution context, like event handlers, style, or script.
• HTML Attribute: If you want to insert untrusted data into typical attribute values such as value, name, width, etc, escape all characters that have less than 256 ASCII value with the “&3xHH;”.
• CSS: Attackers can easily leverage CSS to launch XSS attacks on a web application. Therefore, it’s important to have necessary security measures in place. If you want to put untrusted data into a style tag or a stylesheet, only use it in a property value and avoid putting it in other places in the style data. Steer clear of putting untrusted data into complex properties such as behavior or URLs.
• URL: This rule is specifically when you want to put untrusted data into the HTTP GET parameter value. Consider escaping all characters with ASCII values less than 256 using the “%HH” format. Ensure all attributes are quotes properly as unquoted attributes can be easily broken with various characters such as *, [space], /, %, etc.
• JavaScript: If you want to insert untrusted data into the JavaScript code, the only secure place you can do that is inside a quoted “data value”. Escape all characters with less than 256 ASCII value using the “\xHH” escaping format to prevent untrusted data from switching into another attribute or script context.
• In short, for all of these different contexts, look for an encoding library that handles html entity, html attribute, javascript, css contexts, etc. There are some good libraries out there that have been thoroughly vetted; make use of them!
Implement Input Validation
The idea behind input validation is to consider any untrusted data as malicious. Any data that comes from outside the trusted network or system can be considered as untrusted data.
Input validation is the process of validating that a web application is rendering only trusted and correct data to prevent malicious data from entering into the system and doing harm to the site, users, and database.
Input validation should always be done but can provide a basic level of protection to prevent XSS in forms, as it forbids a user from adding special characters into the fields. The recommended way to do this is to utilize whitelisting which only allows known characters on a web application, thereby helping prevent XSS attacks.
While it provides for a basic level of protection, the recommended approach is to use output encoding as a more robust defense.
Use Security Headers
Preventing all cross-site scripting or XSS flaws in a web application can be difficult, therefore you should also implement ways to contain the impact of a cross-site scripting flaw. For instance, you should set the HTTPOnly flag of your session cookie and other custom cookies you may have that are not accessed by any JavaScript codes you wrote.
Another great way of mitigating the impact of an XSS flaw can be implementing a robust content security policy. Basically, a content security policy is a browser-side mechanism that helps you create source whitelists for the client-side resources of your web application like CSS, JavaScript, images, etc. It uses a special HTTP header to instruct the browser to only render or execute resources from those whitelisted sources.
Further, you can also set the X-XSS protection header to “X-XSS-Protection: 0” to disable the XSS Auditor, preventing it from taking the default browser to handle responses.
Takeaways
While using security layers, such as the methods above, is an effective way to combat many types of XSS attacks, it is crucial to remember that these prevention methods cannot guarantee complete protection of your web application.
Preventing cross-site scripting vulnerabilities also requires that you perform thorough code reviews, automated static testing during development, and dynamic testing once the web application is deployed in the production phase to reveal security vulnerabilities. In addition to this, using secure coding practices will also help prevent security vulnerabilities such as cross-site scripting.
This post was originally published at CypressDataDefense.com.
Top comments (0)