Cross Site Scripting (XSS)

Cross Site Scripting (XSS) refers to attacks in which attackers inject malicious scripts into an application. As a general rule, those attacks are facilitated as soon as the input from a request is copied into the generated response without validating or encoding it. 

An attack occurs when an attacker sends a malicious script (in most cases a browser side javascript) to a different (unsuspecting) user of an application. When the link is clicked, the user’s browser thinks the script came from the application (as a trusted source) and it will execute the script. However the malicious script can access any cookies or other sensitive information retained by the browser and used with the application. A script can rewrite the content of the HTML page. Or even use ajax to get content from the application and send this to the attacker. In smart attacks, this all happens without the user noticing it.

XSS has been widely documented on the Internet. We refer to these sources for more information. In this page some basic examples of Cross Site Scripting as it pertains to the CrossmarX development are described. After, a few countermeasures are given.

Example 1

Suppose an application has a velocity file with the following content:

$request.getUrl()

Lets save this file as "xxs/test.vm" on a server with url "https://server.com".

You can call this file with https://test-server.com/xxs/test.vm, and the result will be:

/xxs/test.vm

But the file can also be called with:

https://server.com/xxs/test.vm?x=%27%22%3E%3Cscript%3Ealert(%22Hai,%20you%20are%20hacked%22)%3C/script%3E%27

As you can notice, Javascript is added to the url. The Velocity file will now generate a HTML page with the script element <script>alert("Hai, you are hacked")</script>, as this is part of the url. When this url is sent to another user by mail or chat and this other person clicks on the link, the script is executed in the browser of the attacked person.The result is:

 

 

An attacker will use more dangerous content instead of the simple Javascript alert.

Example 2

The Javascript does not have to be printed in the resulting document. Suppose an application has a Velocity file with the following content:

<head>
    <meta property="og:title" content="A title" />
    <meta property="og:description" content="A description" />   
    <meta property="og:image" content="https://blueocean.com/image.png" />
    <meta property="og:url" content="$request.getBase()$request.getUrl().substring(1)" />
</head>


The og properties are often used for sharing information of this page in social media. In this example the Javascript will be integrated in the content of the property og:url. If this file is called with the same call as above, this has the same effect: the Javascript is executed.

Therefore, you can never take the result of $request.getUrl() and print this in the page. For og:url properties you have to find safer ways to get the value of the content, e.g. if the file is a class template, you can use $record.getUrl().

 

Types of cross site scripting

We distinguish two types of cross site scripting:

  • Persistent XSS: this is when the malicious content is stored in the database and deploys it's attack when retrieved from the database to display in the browser.
  • Non-persistent XSS: when the malicious content is contained in a request to the application. The attack is deployed when the content is handled by a Velocity file and displayed in the browser.

Another important distinction is HTML and non-HTML content:

  • Non-HTML: This content can be escaped before displaying. This prevents all currently known types of XSS attack. Escaping is done automatically in engine screens, and when using Velocity methods like $record.getLabel()
  • HTML: This content can't be escaped. Therefore this content has to be trusted to be displayed in the browser.

 

Developing around XSS

Persistent XSS

There are two field properties of importance when developing around XSS threats:

  • HTML
    Fields with datatype 'memo' can be set to allow HTML content. The default value for this property is 'Reject < and >'. With this option, the sumbitted text is searched for '<' and '> ' characters, deleting them wherever they are found before submitting the text to the database. A warning is generated whenever these characters are found.
  • Allow scripts in html
    Fields with datatype 'memo' and the property 'HTML' set to either one of the values 'HTML', 'HTML editor' or 'HTML editor always' can be set to allow scripts. If this property is set to false, the content is checked if it contains JavaScript. This is done on currently known patterns. This check can never be exhaustive.

Non-persistent XSS

In this case the source of the attack is a malignant request. This is only dangerous if the user can be made to execute an url.

Developing around this threat doesn't seek to prevent this from happening, but seeks to mitigate the consequences of opening a bad url.

The main tenet here is to never print data straight to the screen. Always escape first. The method Request.get(string) checks the text on the basis of known patterns. Again, this check can never be exhaustive.