How To Prevent Cross-Site Scripting (XSS)

Preventing Cross Site Scripting (XSS)

For a description of Cross-Site Scripting (XSS), see the article entitled “What Is Cross-Site Scripting?“.

For an explanation of how to detect Cross-Site Scripting (XSS) vulnerabilities, see “How To Test For Cross-Site Scripting“.

The reason that Cross-Site Scripting (XSS) remains the most common type of website vulnerability is that it can be tricky to prevent.  The good news is that if you diligently apply the guidelines referenced below, you will stay out of trouble.  (Of course this doesn’t mean that you shouldn’t test for it anyway).

Preventing Cross-Site Scripting (XSS) is accomplished using a combination of the following tactics that serve to prevent malicious input from breaking the content/code barrier in HTML.

Input Validation

The first line of defense for any web-application is to validate the data that is input to the application.  Untrusted inputs must be validated to ensure that each item meets the expectations of the application before it is processed. [Note: This presupposes the existence of some Security Requirements that describe the verifiable characteristics of each input such as: allowable character set, input length, data type, boundary values, acceptable Regex pattern, etc.]  The application must whitelist validate input against a definition of what is acceptable, not against a list of what is not acceptable.  This CAN occur on the Browser for end-user convenience, but MUST be performed on the server after the request is received.  Requests that fail input validation must be rejected with a suitable error message for the end-user.  Inputs that fail validation should not be returned in any response.

It is possible that diligent input validation may eliminate the possibility of Cross-Site Scripting (XSS), because it may result in the rejection of any and all malicious input that would be exploitable.  It is also possible that the application requirements mandate the acceptance of certain characters in certain fields which could be problematic because they have meaning within HTML, such as: {>,<,’,”,;, (,) }.  It is this latter case that warrants output encoding to neutralize the special meaning of those characters to the Browser.

Output Encoding

The second line of defense against Cross-Site Scripting (XSS) is to neutralize any potentially troublesome characters within inputs being returned in responses.  That essentially means preventing HTML meta-characters from being interpreted as such, and ensuring they are treated as data and not control characters.  Unfortunately, this is where things become a bit tricky, as the context in which the data appears in the HTML influences what type of encoding must be used to protect it.  The good news is that there are both guidelines and libraries to help you choose and implement the right encoding scheme.

HTML Entity Encoding

The simplest scenario is called the “HTML context”, and it refers to inputs that the designer expects the to be rendered as data and appear as page content.  For example, the response page might contain the following, in which the name originated as user-input:

Name: John Smith

We know from our review of “What Is Cross-Site Scripting (XSS) ?” that malicious input might contain an HTML “script” element and produce the following response:

Name: John Smith <script>alert(‘xss’);</script>

which would break the HTML content/code boundary and execute the contents of the script element as JavaScript.  Note that the end-user would never see the “script” element unless they viewed the page source but would see the pop-up (in this example).

Preventing Cross-Site Scripting (XSS)  in the HTML context is done with HTML Entity Encoding, which essentially replaces HTML control characters with special codes that mark them as data:

Character HTML Entity
< &lt;
> &gt;
& &amp;
&apos;
&quot;

So modifying each input that will appear as HTML content by replacing each character on the left with the corresponding sequence on the right will force those characters to be interpreted as data, effectively preventing Cross-Site Scripting (XSS) exploits.  In the example above, this would means that the end-user would see the “script”element, and it would not be executed.

Encoding For Other Contexts

Unfortunately, the power and complexity of HTML is such that there are many other contexts into which inputs can be inserted in HTTP responses.  The OWASP XSS (Cross-Site Scripting) Prevention Cheatsheet does a great job of identifying contexts into which inputs can safely be injected and how to properly encode them.  Critically, it also identifies contexts in which it is NEVER safe to inject inputs.  It is essential that developers are familiar with these guidelines.

Microsoft Visual Studio and XSS Prevention

If you are using a recent version of Microsoft Visual Studio .NET, you will find that the Microsoft Anti-XSS library is now integrated for your convenience.  As the name implies, this is a family of functions that you can use to encode inputs to neutralize them for output back to a Browser.

ASP .NET and XSS Prevention

One of the benefits of using ASP .NET is that MOST but NOT ALL controls will automatically HTML Encode and URL encode (check your documentation) the values to be rendered by the Browser.  Of particular concern are ASP .NET Label controls, since they are often used as a means to display data in a read-only manner.  Be sure to HTML encode the values assigned to ASP .NET Label controls, as they are not automatically encoded.

Here is an OLD summary matrix of controls and whether they are automatically encoded; we cannot vouch for its accuracy with your version of ASP .NET.  If you are not sure of the status of a particular control, TEST IT !  In fact, even if you are sure, TEST IT !

Java and XSS Prevention

Although the Java distribution does not integrate encoding functions, there are a number of resources to drawn from in the Java world, notably the OWASP Java Encoder Project.  It is also worth noting that some tag libraries will automatically HTML encode values.  For example the JSTL Core Tag Library, “out” tag automatically defaults to a mode that HTML encodes its output.

PHP and XSS

PHP also provides functions for HTML Entity Encoding.

Other Considerations

Some Browsers and web-servers (notably IIS) attempt to detect and flag malicious XSS input.  They are effective in certain cases and this can provide developers with a false sense of security because it is almost always the case that a “Filter Evasion” string or a malicious XSS payload encoded as octal, hex, or decimal will bypass the filter and exploit a vulnerable application.

For an explanation of how to detect Cross-Site Scripting (XSS) vulnerabilities, see “How To Test For Cross-Site Scripting“.

About Affinity IT Security

We hope you found this article to be useful. Affinity IT Security is available to help you with your security testing and  train your developers and testers.  In fact, we train developers and IT staff how to hack applications and networks.

Perhaps it was a network scan or website vulnerability test that brought you here.  If so, you are likely researching how to find, fix, or avoid a particular vulnerability.  We urge you to be proactive and ensure that key individuals in your organization understand not only this issue, but also are more broadly aware of application security.

Contact us to learn how to better protect your enterprise.

 

 

Although every effort has been made to provide the most useful and highest quality information, it is unfortunate but inevitable that some errors, omissions, and typographical mistakes will appear in these articles. Consequently, Affinity IT Security will not be responsible for any loss or damages resulting directly or indirectly from any error, misunderstanding, software defect, example, or misuse of any content herein.