Cross Site Scripting is the second most prevalent issue in the Open Source Foundation for Application Security (OWASP) top 10 – it's found in roughly 2/3 of all applications.
While automated tools can find some of these problems, there are also automated tools designed to detect and exploit these vulnerabilities.
What is Cross-Site Scripting?
XSS attacks occur when data enters a web application through an untrusted source (like a web request), and is sent to a user without being validated.
XSS can cause scripts to be executed in the user's browser, resulting in hijacked sessions, website defacement, and redirection of users to malicious sites.
Essentially an attacker is inputting malicious code into a section for user input which the server expects to be data (but is instead code designed to be executed).
And if you don't handle it appropriately, the malicious code can break out of the 'data plane' and execute as normal code (the 'control plane').
We can group most XSS attacks into two categories: stored and reflected. A third type, which is less common, is referred to as DOM-based XSS.
Reflected XSS (Impact: Moderate)
This is the most basic type of XSS, wherein an application receives data and then includes that data in the response to the user in an insecure way.
For example, if an attacker convinces a user to click this phishing link:
If the legitimate site doesn't process the data and just returns it to the user, the user's browser will execute the malicious code.
Stored XSS (Impact: Severe)
Stored XSS occurs when the injection is permanently stored on the target's servers, such as a message in a forum or comment section, in a database, and so on. Essentially this means that the exploit impacts every visitor to the site/application.
For example, if a site allows users to comment and then displays their comments, a user could enter the following:
If the site doesn't check user input appropriately, it could result in the script executing for any other user who sees this message.
DOM-based XSS/Client Side XSS (Impact: Moderate)
The big difference between reflected and stored XSS and DOM-based is where the attack is injected.
Reflected and stored XSS are server side issues, while DOM-based is a client (browser) side issue. DOM-based XSS occurs in the DOM (document object model) instead of as part of the HTML.
Rather than inserting malicious code into the page, this attack will allow the legitimate page to load, then leverage user input to add HTML to the page, executing the malicious script. This takes advantage of the increasing amounts of HTML generated by the client.
For example, an attacker could social engineer a victim into clicking on a malicious link (such as http://www.legitimatewebsite.com/contact#<script>malicious code</script>). The website will receive the legitimate request for the page, but not the malicious fragment (because browsers don't send anything after the # character to a site's server). The victim will see the legitimate website, but the victim's browser will also execute the malicious script.
Due to the way this attack works, server-side protections won't prevent it as the malicious code isn't being sent to the server at all.
Mitigation Measures for XSS Attacks
Mitigating effectively against XSS attacks requires a combination of the below measures, which, when you use them together, can provide a robust defense against XSS.
Avoid inserting user-supplied/untrusted data anywhere other than specified locations
This is the first and most important rule. Encoding, escaping, validating, and filtering input is extremely difficult and very complicated.
It's much easier to limit the number of places where someone can input untrusted data. The safest assumption is that all untrusted data is malicious.
Ideally, all input should be validated against a list of acceptable values.
It's particularly important to ensure output is encoded at any point where it is exposed, as the same data could be stored and displayed in multiple places.
Choose Frameworks Carefully
Use frameworks which provide automatic escaping functionality (like Go Templates) or those which have native defenses against XSS (like .NET's request validation).
Set the HttpOnly Flag
Use Response Headers
Educate Developers about Security
Education specifically targeted at developers, like 'Security Champions' programs which pair application security team members with developers, are important. They can help educate developers about security vulnerabilities (like XSS) and how to prevent them.
Have a Content Security Policy
A content security policy (CSP) can help you detect and mitigate XSS and other data injection attacks.
They set allowlists for sources of trusted content and can apply only to sensitive pages (like payment pages) or, ideally, to the entire site. They can even provide notifications if content is loaded from a page which it should not.
They're fairly easy to deploy – just add the Content-Security-Policy HTTP header to the webpage and any directives that are appropriate.
The CSP Fiddler Extension can help you generate a baseline CSP. The tool will build a policy around reports submitted by the browser, creating a changeable baseline policy.
Additionally, you can use Report URI, run by Troy Hunt and Scott Helme, to get alerts on CSP violations in order to more proactively monitor your sites.
Typically a policy consists of a series of directives which will describe the policy for a type of resource or area. One of these directives, sub-resource integrity checks, is used to ensure that a browser verifies that third party content (from sources like a CDN) is delivered without being manipulated.
Essentially, a provided cryptographic hash must match the loaded file. If a hacker modifies the third party's content, the site simply will not load the malicious content.
The problem is that if the content provider updates the file or makes legitimate changes, the content will also not load (because the hash will have changed).
While browsers do not universally support this feature, for those browsers which lack the feature, using it won't break the site (it simply won't leverage the technology).