XSS Cheat Sheet

Introduction 

Cross-site scripting (XSS) represents a significant security flaw commonly encountered in websites and web applications. This vulnerability enables malicious individuals to insert harmful code (client-side scripts) into web pages viewed by users. When executed by the user’s browser, this code can perform various undesirable actions, such as altering the website’s behavior or appearance, stealing sensitive data, or performing unauthorized actions on the user’s behalf.

The root cause of XSS vulnerabilities lies in the failure to properly validate or escape user input or dynamic content, allowing client-side JavaScript to be injected and executed. Hence, any part of your application that handles user input is susceptible to XSS risks. There are several forms of XSS, categorized as follows:

  • Reflected (non-persistent) XSS In this form, the injected malicious script appears immediately to the user without proper content sanitization.
  • Stored (persistent) XSS This variant is more severe, as the attacker’s data is stored by the server and displayed to other users during regular browsing without adequate HTML escaping.
  • DOM-based XSS In this case, the injected malicious code doesn’t reach the web server but is instead executed by client-side JavaScript code on the client-side.

Failing to address XSS can expose your application to various security risks, significantly impacting both the organization and end-users. It is crucial to identify and mitigate XSS vulnerabilities in your web application before they lead to severe security problems. Consequently, this cheat sheet compiles a range of methods aimed at identifying and preventing or minimizing the effects of XSS vulnerabilities.

Identify XSS: Manual Code Reviews and Testing

Code review has the primary objective of uncovering security vulnerabilities within applications and pinpointing their precise origins. This process entails a thorough examination of the application’s source code to ensure it possesses the necessary self-defensive capabilities for its specific environment. OWASP emphasizes the critical nature of code review by stating that the absence of such scrutiny virtually guarantees the existence of issues in the application. While tools can assist in this endeavor, they cannot grasp the context, making human verification indispensable. This is where manual security code review assumes a crucial role.

If manual code review is done correctly, a penetration test afterward using automated tools should discover little or no vulnerabilities. Interestingly, OWASP provides a detailed guide on manually reviewing code for XSS vulnerabilities, including a complete manual testing guide for reflected XSS, stored XSS, and DOM-based XSS vulnerabilities for your reference. The following manual processes can be used to identify common XSS vulnerabilities:

  • Identify code that outputs user input Failure to properly sanitize user input in code exposes it to the risk of Cross-Site Scripting (XSS) vulnerabilities. To ascertain whether your code is placed within an attribute, you can press Ctrl + U to inspect the page output source in your browser. If it is, you can test the output by injecting the following code: “onmouseover=alert(‘hello’);”.
  • For testing purposes, you can use this script: <script>alert(document.cookie);</script>. However, if the code you are reviewing filters out < and > characters, you should try the following script instead: &{alert(‘hello’);}”. This allows you to assess whether the code effectively mitigates potential XSS threats.
  • Check that output is encoded Ensure that HTML output, which may include various forms of input, is properly encoded using HtmlEncode. Similarly, make sure that URL strings are encoded using Uuencode. Input data can originate from diverse sources, such as query strings, form fields, cookies, HTTP headers, and data read from shared databases used by other applications. Failing to apply these encodings puts your application at risk of XSS vulnerability. Implementing proper encoding measures not only enhances security but also prevents the browser from treating the HTML content as an executable script, thus mitigating potential XSS threats.
  • Identify code that handles URLs Code that governs URLs can risk XSS and other vulnerabilities. Review your code and systems as follows:
    • Check that your web server is updated. If your web server is not up-to-date with the latest security patches, it could be vulnerable to directory traversal attacks.
    • If your code filters for “/”, an attacker can easily bypass the filter by using URL encoding (percent-encoding) for the same character. For example, the percent-encoding for “/” is “%c0f%af”, which could be used to bypass the filter as shown in the following URL: http://www.abc.com/..%c0f%af../winnt.
    • If your code processes query string input, check that it constrains the input data and performs bounds checks. Also, check that the code is not vulnerable if an attacker injects a massive amount of data through a query string parameter like the URL shown here: http://www.abc.com/test.aspx?var=InjectHugeAmountOfDataHere.
  • Unit test your codes Unit testing is a software testing method by which individual units of source code are tested to determine whether they are fit for use. Unit testing aims to isolate each part of the program and show that the individual components are correct. Use unit testing to make sure that a particular bit of data is correctly escaped. Unit testing helps to identify XSS and other flaws early in the development cycle. If possible, unit test every place where user-supplied data is displayed. After you find and fix an XSS bug in your code, consider adding a regression test for it.
  • Perform these basic tests on your application Create a test user profile and use that profile to interact with your application. Insert strings that contain HTML and JavaScript meta characters such as  >’>”><img src=x onerror=alert(0)> into all application inputs, such as forms, URL parameters, hidden fields, or cookie values.

If your application doesn’t correctly escape this string, you will see an alert and know that something isn’t right. Wherever your application handles user-supplied URLs, enter the following javascript code: alert(0) or data:text/html,<script>alert(0)</script>. All of these can help identify stored XSS bugs.

Identify XSS: Automated Application Testing

Detecting XSS vulnerabilities in web applications can be achieved through standard security testing techniques and tools. Notable methods include:

  • Static Application Security Testing (SAST) SAST secures applications by reviewing their source code to identify potential vulnerabilities or insecure practices. Since it operates independently of the application’s runtime, waiting for deployment is unnecessary, allowing for faster and more cost-effective vulnerability detection. Employing a white-box approach, SAST scans the source code and components to pinpoint security flaws.
  • Dynamic Application Security Testing (DAST) DAST tools interact with applications via the front end to uncover potential security vulnerabilities. Lacking access to source codes, they rely on black-box testing strategies, performing attacks during code execution. Dynamic analysis utilizes techniques like fuzzing, which tests the application with random, malformed data to uncover XSS flaws.
  • Interactive Application Security Testing (IAST) IAST combines the strengths of SAST and DAST. It examines code for XSS and other security vulnerabilities while the application is running, interacting with its functionality.

Leveraging these techniques enables swift testing and detection of XSS vulnerabilities in web applications. Web vulnerability scanners, such as Netsparker, Acunetix, Veracode, and Checkmarx, are powerful tools that automatically crawl the entire website or application, checking for XSS and other security flaws. While these scanners may not be tailor-made for specific applications, they efficiently detect obvious vulnerabilities and implement many of the testing techniques discussed earlier. Furthermore, they allow for vulnerability scanning, report generation, and even attempt automatic fixes.

Prevent XSS

First and foremost, it is imperative to acknowledge that no solution can be guaranteed foolproof, given the swift evolution of technology and the ever-advancing sophistication of attacks. By grasping the fundamentals, you can prepare to counter future attack techniques effectively. The following are some recommendations to prevent or minimize XSS vulnerabilities:

  • Use Secure Coding Practices To secure your web application and prevent XSS attacks, follow sound coding practices. Be cautious when using user input to generate output for other users. Adhere to the golden rules of user input: treat all data as potentially harmful until verified, and filter data at the boundary between untrusted and trusted domains. By implementing security coding practices recommended by OWASP, you can significantly decrease common vulnerabilities, including XSS.
  • Filter User Inputs To prevent XSS vulnerabilities, ensure all external data (user input) passes through a filter that removes hazardous tags and attributes like <script>, <applet>, <html>, <frame>, <img>, <embed>, and JavaScript commands. You can either develop your own filter mechanisms or utilize reliable, pre-existing libraries. However, be aware that experienced attackers might attempt to bypass simple filters using techniques like hex encoding, Unicode character variations, line breaks, and null characters. As a result, user input filtering alone may not suffice against advanced XSS attacks. Consult the OWASP filter evasion cheat sheet for guidance on guarding against such exploits.
  • Use Escaping Techniques A common technique for preventing XSS vulnerabilities is “escaping”. When you use escaping techniques, you effectively tell the web browser that the data you are sending should be treated as data and not be interpreted as a control character or code. Thus, if an attacker manages to inject an XSS script on your page, the malicious code will not be executed if it is properly escaped. However, to guarantee the security of your web applications, you must master the use of escaping techniques for HTML, JavaScript, CSS, and sometimes XML data. This is because these languages require different forms of escaping for each context.

In HTML, you can escape dangerous characters by using HTML entities such as &# sequence followed by its character code. For example, ‘&lt;’ and ‘&gt;’ are the HTML encoding for the ‘<‘ and ‘>’ characters, respectively. If you include: <script>alert(‘testing’)</script> in the HTML of a page, the script will execute. But if you include the character codes in the HTML of a page as shown here: &lt;script&gt;alert(‘testing’)&lt;/script&gt;

It will print out the text “<script>alert(‘testing’)</script>”, but it will not execute the script. By escaping the <script> tags, we prevented the script from executing. Use HTML escaping when untrusted data is inserted between HTML opening and closing tags.

Similarly, use JavaScript or CSS escaping when untrusted data is inserted inside one of your scripts or CSS styles, as the case may be. This includes event handlers such as on mouseover and upload and certain HTML attributes such as style. For example:

<script>alert('If this data is untrusted, it must be JavaScript-escaped.')</script>

<body onload="If this data is untrusted, it must be JavaScript-escaped.">

You can do all the escaping by writing the code yourself. However, writing your code for escaping user input and adequately and consistently applying it is extremely difficult. Therefore, we recommend using existing libraries such as OWASP ESAPI, Microsoft AntiXSS (best suited for Microsoft environment), or web development frameworks or templates that provide context-aware auto-escaping. If you use templates to generate HTML within JavaScript, Closure Templates and Angular provide built-in escaping capabilities.

Other things you can do to prevent XSS vulnerability or minimize the chances of XSS attacks include:

  • Learning the best practices for your server-side and client-side technologies, such as using HTML sanitizer or configuring your browser to use a proxy that intercepts and scans traffic such as Burp Proxy and ratproxy to help identify problems.
  • Using a web template system or a web development framework with context-aware auto-escaping.
  • Manually escaping user input (if template system with context-aware auto-escaping is not feasible)
  • Understanding common browser behaviors that lead to XSS.

Summary 

Detecting and mitigating XSS vulnerabilities in web applications is not a simple task with a one-size-fits-all solution. It requires a balanced approach, combining human effort through manual code reviews and technology support via automated tools like vulnerability scanners. On one end of the spectrum, a developer, and an application security reviewer may manually inspect codes using a text editor. On the other end, an expert security team may utilize advanced Static Application Security Testing (SAST) tools.

Automated tools excel at assessing vast amounts of code and identifying potential issues. However, human verification is crucial to determine if these results are exploitable and assess the risk to the organization. Automated tools have limitations and cannot cover all potential vulnerabilities, leaving significant blind spots that human reviewers must address. Emphasizing a combination of manual code reviews and automated testing is essential, as no testing methodology guarantees absolute security. This approach will significantly reduce the likelihood of an XSS vulnerability within your application.