Cross-Site Scripting (XSS) is a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end-user. Flaws that allow these attacks to succeed are quite widespread and occur anywhere a web application uses input from a user within the output it generates without validating or encoding it.
How XSS works
The basic idea behind XSS is rather simple. Malicious attackers use various techniques to smuggle harmful scripts into web applications. When an unsuspecting user visits a site hosting the injected malicious code, it will run in the victim’s browser with the same permissions that the victim’s browser would have when visiting any other legitimate site. This all seems harmless enough – until you realize that this also means that these same scripts have access to anything the legitimate site can do. Cookies, session tokens, and even passwords are all accessible to third-party scripts running on sites hosting them.
Different kinds of XSS vectors: Non-persistent vs. Persistent(Reflected)
The payload resides in local browser storage (i.e., cookies) that is associated with a malicious domain controlled by the attacker. A successful attack occurs when a victim, who either is already logged into an application or who is still in process of authenticating the application, clicks on a malicious link which directs them to the vulnerable domain. The injected script contained in this malicious link will then be executed automatically within the security context of the browser.
The payload resides in local browser storage (i.e., cookies) that is associated with a legitimate domain, e.g., http://example-bank.com/. When an authenticated victim, while interacting with an application hosted on example-bank.com/, follows a malicious link delivered by an attacker to another site (e.g., http://evil-attacker.com). The injected script contained in this malicious link will then be executed automatically within the security context of the browser.
The following are some of the best practices for preventing XSS attacks:
- Use data validation and escaping where appropriate.
- Don’t accept arbitrary HTML, especially from a user’s own input, as it can be escaped and then displayed back to the browser without first being validated for malicious content.
- Use HTTPOnly cookies (or equivalent protection mechanism for your particular web framework) to mitigate the risk of browser-side script accessing or modifying cookie values, which would allow an XSS attack to succeed.
- Keep cookies persistent for as short a time as possible; using browser-specific techniques (e.g., only setting the HttpOnly flag in recent versions of Firefox). The longer a user’s session is valid, the greater the chance an attacker will be able to steal it.
- Ensure that all input is validated on both the client and server sides; i.e., make sure that no executable code is reflected in any part of the HTML page returned to the browser.
Frequently Asked Questions about Cross-Site Scripting
How do I know if my site is susceptible to this type of attack?
Most web applications written in PHP, .NET and Java contain numerous instances of code that interact with end-users via the filesystem or network. It is strongly recommended that you conduct a comprehensive security review by someone who specializes in performing such assessments against your application. If your developers do not specialize in security (or you lack dedicated web application security resources), we recommend hiring a professional penetration tester to carry out an assessment of your site(s).
How does XSS affect mobile apps? Is it different from traditional websites?
What is the difference between reflected and stored XSS?
Stored XSS occurs when an application takes user input, stores it on the server and displays it back to other users without proper validation or escaping. In some cases, this may lead to persistent problems of cross-site scripting within an application. Reflected XSS happens when code is echoed back onto a page from a request, as opposed to being stored on the server for future use. The differences between these two kinds of injections are only theoretical in nature since both kinds result in malicious scripts executing on end-user browsers.
What is DOM-based XSS?
DOM-based XSS appears when an application dynamically generates HTML documents on the server and stores them in the browser’s memory (DOM) without properly escaping it. Since this data does not go back to the server, it cannot be detected with traditional vulnerability scanners that send requests to web servers. However, this vulnerability can be detected by client-side penetration and fuzz testing tools and services.
What is the difference between XSS and Cross-Site Request Forgery (CSRF)?
Both attacks involve unauthorized commands being transmitted to a web browser via an unsuspecting victim. The main difference between them is that XSS involves code injection while CSRF invokes dangerous actions through forged HTTP requests.
How does an XSS attack look like?
An XSS attack is generally made up of the following actions:
- A user visits a compromised website or clicks on a link to an attacked site sent by an attacker via e-mail or instant message. The malicious code is executed in the browser because the site was compromised and/or the user has clicked on a carefully crafted link pointing to code injected onto this particular site.
- The malicious page sends HTTP requests containing stored information (e.g., session cookies) back to the server that originally generated them, potentially capturing this data within web applications’ databases that are not fully protected against SQL injection attacks. This would then lead to other database records being altered as well, even though these were generated using different HTML pages.
What are XSS vulnerabilities?
Any failure in an application’s security that allows the execution of unauthorized code within a user’s browser is defined as an XSS vulnerability. For example, if the attack payload is stored on the server and returned to other users (without proper validation or escaping) who access this data via HTTP requests directly, then the flaw is called reflected XSS. When there are no direct HTTP requests involved but instead, information is simply stored on the database without any validation, this would lead to persistent problems of cross-site scripting within an application known as persistent XSS.
What do I need to know about cross-site scripting protection and mitigation?