Understanding Cross-Site Scripting: How To Prevent An XSS Attack

Hacker looking at website code

Last Updated on 7 June 2023 by admin

Previously, we have discussed what is Cross-Site Scripting (XSS) and how an attacker can use an XSS vulnerability to their advantage. In this article, we will be covering tips for how to prevent an XSS attack.

Sanitize user inputs

Any user input accepted by your web application should not be trusted by default and subject to rigorous checks before being used by the application. These checks should be performed server-side, and include checks such as filtering user input and encoding user output. All parts of a request can be manipulated, which is sometimes overlooked. Examples of this include user agents, content types, cookies and more. All of these should be considered untrusted as an attacker can use them as a means of exploitation.

Client-side validation isn’t enough to prevent an XSS attack

It isn’t uncommon for client-side validation to be implemented as a sole line of defence. However, client-side validation can be bypassed trivially by attackers and is not enough to protect web applications and their users. Tools such as Burp Suite and OWASPs ZAP exist to allow an attacker to intercept traffic before being sent to a server, approving modification of the entire request. This means any validation that was present in the browser no longer applies, and data can be input outside of the constraints that developers may have anticipated.

Although client-side validation can be bypassed, it is worth implementing as part of a multi-layered security strategy on the application.

User input filtering

Another method to include is filtering user input. An example of this would be removing all <script> tags from the input received within a first name field of a sign-up page. Developers may try and implement their own filters, but this can still lead to compromise when more obscure and advanced payloads are used. With that being said, it is recommended to look at filtering libraries appropriate for your technology stack which are regularly updated and maintained. The sophistication of payloads is increasing by the day, so why would you use an old, outdated library as a line of defence?

Appropriately encode data output

When some form of user-controlled input is inevitably reflected in response, the output should be encoded to prevent the browser from interpreting it as content to render. Depending on which context the input is placed in depends on what type of encoding needs to be used. OWASP provides a comprehensive XSS prevention cheat sheet with how to implement this and more tips on XSS prevention.

Embrace a secure development lifecycle

Arguably one of the most important tips to defending any web application, not just applicable for XSS attacks, is ensuring the application is part of a secure development lifecycle (SDLC). If implemented properly, an SDLC helps guide the development of a robust and secure application from its conception. This reduces the amount of time and expense needed to remediate vulnerabilities found in the application if an SDLC was not used. Not to mention, the potential risk to a company’s reputation if a security breach were to occur due to weak defences.

Microsoft has released extensive material on their SDL practices and on how to properly integrate an SDLC. OWASP also has a plethora of resources on SDLCs. If an SDLC is properly integrated into the current applications lifecycle, you can almost guarantee a reduced amount of vulnerabilities.

Additional XSS defences

Additional defences can also be implemented which may completely thwart XSS from happening, and if it does happen, reduce the severity. For example, if a response does not (under any normal circumstances) contain any HTML or JavaScript, the content type can be forced with the X-Content-Type-Options and Content-Type headers, meaning if a payload is reflected back the browser will not interpret it, resulting in no JavaScript or HTML being executed.

The X-XSS-Protection header can be implemented to further improve security. The purpose of this header is to stop pages from loading when reflected XSS is detected. There are some different options that can be used with this header, all of which can be reviewed here.

Content Security Policy (CSP) can also be used to help mitigate and control the extent of any XSS attacks. This is done via the Content-Security-Policy header which is used to specify domains that are considered trusted when it comes to script execution.

None of these tips should be used as a sole line of defence, and instead integrated with current security controls to further improve the security posture of the application(s).

Summary

It’s important to realize that a multi-layered approach should be adopted when it comes to preventing XSS, and all security practices in general. As attacks become more advanced, it’s not uncommon for defences to start failing to protect against the more obscure types of payloads that attackers take advantage of. The techniques covered in this article, along with all referenced material, provide a robust guideline for how to implement a multi-layered defence approach to effectively combat XSS.