Skip to Content
Cross Site Scripting is among the most widespread security problems today.
There are several reasons for that:

  • Most people don’t understand it.
  • Most of the people who understand it, underestimate it.
  • Most of the people who understand and don’t underestimate it, address it insufficiently.

I performed many security assessments over the last years and more than 75% of the bugs discoverd were XSS issues.
Note that most of the companies I checked were aware of the issue…

So first, let’s talk about what XSS is.

Definition: By means of Cross Site Scripting an attacker can manipulate HTML pages (that are not his/her own) that someone else will read in a browser at a later time. Most attacks target web servers, but XSS is an attack against the client by taking advantage of a software flaw on the server. In other words: if you don’t code your web apps securely you jeopardize the safety of your customers (or your employees) data through XSS.

Now, how can an attacker manipulate HTML pages on someone else’s server?
On many occasions user input entered in one page will be displayed again in another page.

  • Example a: Incorrect user names in logon screens will be displayed again (together with an error message).
  • Example b: Text posted in a forum can be read by other users.

Therefore, attackers will look out for web sites that display what a user enters in a URL parameter or they will post information in a forum. Whenever user input is written back to HTML, this is a potential attack vector for XSS.

In what way is this HTML manipulation an attack?
HTML is based on tags that browsers either render as visible objects (like graphics or input fields) or interpret and execute (like Javascript or ActiveX controls). If someone can change the HTML code, then this person might add whatever tags they want to the document (usually SCRIPT tags). Those tags will be executed when some else opens the manipulated page (either by following a link or by reading a posted note, e.g. in a forum). When that happens arbitrary Javascript/ActiveX/Java code might run on a victim’s machine.

Now that we know what XSS is, what makes it dangerous?
Well, if a hacker can execute Javascript in your browser a lot of bad things can happen:
Among other things he could

  • send your browser into an endless loop
  • access all data you entered in a form (login credentials, credit card numbers, ssn, …) and send it to a rogue server
  • access your cookies (e.g. your SAP SSO2 ticket) and continue your session (you really don’t want that to happen!)

And if a hacker can execute ActiveX commands in your browser she might

  • format your hard drive
  • read/change/delete local files
  • access other programs

By that way: you do use restrictive settings for ActiveX in your browser, don’t you?

In short, through XSS an attacker can do substantial damage to your clients / customers and your web application makes it all possible.

So, now that we understand the risk, let’s do something against it!
(Note that all example codes are written in Java)

First of all, note that XSS is an output encoding rather than an input validation poblem. Therefor there is no (failsafe) generic way to handle XSS during input validation. You must address the problem when writing output back to HTML. That means ANY place in your code where input is written back to HTML.

Here is a code fragment that produces an XSS problem:

public void doContent(...) { ... String s; if ((s = request.getParameter("user")) != null) { response.write("
Applicant:" + s + ""); } ... }

If you enter

user=Mulder

then the HTML will contain


Applicant:Mulder

But if you enter

user=

then the HTML will contain


Applicant:

and an alert will pop up in the browser. (Of course an alert message is harmless, but I usually use it as proof of concept that I can execute ANY code)

This is the moment when most people say: “That’s easy to block – just remove all So let’s better focus on the official SAP counter measures that work.

The best way to deal with Cross Site Scripting is to work with Web Dynpro (ABAP and Java). Web Dynpro does all the tag rendering for you and neutralizes XSS automatically (unless you do REALLY fancy things ).
Yet another reason to use Web Dynpro…

But if you’re designing your own HTML pages (working with SAP J2EE engine or the SAP Enterprise Portal) there are some functions designed by SAP that can come in handy.
In order to understand them, let’s take a closer look at XSS…

There are actually 4 different cases where XSS can occur:

Case 1 (Output BETWEEN tags)

[CASE1]  
Username[CASE1]

Sample Attack patterns

  
Username

Case 2 (Output INSIDE tags, but output is not a URL or style)

[CASE2]>

(Make sure you always enclose values in quotation marks)

Sample Attack patterns

...
400 src='bad_banner.jpeg'>

Case 3 (Output is a URL or style)

Sample Attack patterns

Case 4 (Output is inside a SCRIPT context)

[CASE4]; [CASE4] 

Sample Attack patterns

"); var a = alert(); alert(); 

For each of the above cases there is a function in class StringUtils:

[CASE1] Output BETWEEN tags

static String escapeToHTML(String input) static String escapeToHTML(StringBuffer sb, String input, int maxLength) static String escapeToHTML(String input, int maxLength)

[CASE2] Output INSIDE tags, but output is not a URL or style

static String escapeToAttributeValue(String input) static String escapeToAttributeValue(StringBuffer sb, String input, int maxLength) static String escapeToAttributeValue(String input, int maxLength)

[CASE3] Output is a URL or style

static String escapeToURL(String input) static String escapeToURL(StringBuffer sb, String input, int maxLength) static String escapeToURL(String input, int maxLength)

[CASE4] Output is inside a SCRIPT context

static String escapeToJS(String input) static String escapeToJS(StringBuffer sb, String input, int maxLength) static String escapeToJS(String input, int maxLength)

Why 4 functions?
Reason 1: Performance. To counter some XSS cases, complex computations must be performed, while for other cases the encoding is trivial. If there would only be one function this would put unnecessy stress to the server.
Reason 2: Context. Escaping is about rendering characters and/or commands useless by choosing an alternative but harmless representation. Unfortunately HTML is three languages in one: HTML, Javascript and CSS. Each with their own syntax. Escaping in HTML means replacing it with while escaping it in Javascript means replacing it with \”
If there would be only one function it would use at least one wrong escaping sequence when called in both of the above cases.

Why an optional maxlength parameter?
This parameter acts as a second line of defense in case someone finds a way to circumvent the filter used. So, whenever you know how many characters any given input should have at most, you should specify that parameter. The less characters are allowed the less likely it is that a real attack can be executed. Try to write a 20 byte XSS exploit…

How to work with the functions

  1. Find out which of the 4 cases applies to your output context
  2. Pick the corresponding function
  3. Make a length restriction were possible
  4. Wrap your output in the function
  5. Test your countermeasure

Advice: encode your data as close to writing it into HTML as possible. If you encode too early you might run into problems when you do some data processing. (Imagine you write an HTML encoded name into your database.)

To find the proper encoding function, let’s first go back to our coding example and analyze it:

public void doContent(...) { ... String s; if ((s = request.getParameter("user")) != null) { response.write("
Applicant:" + s + ""); } ... }

Now we apply the above methodology:

  1. We render the user input between and – this means output is between tags, ergo case 1 applies
  2. The proper function to call is escapeToHTML
  3. We assume the name can never be longer than 50 characters
  4. We insert the function at the exact point where we write the string to HTML:
public void doContent(...) { ... String s; if ((s = request.getParameter("user")) != null) { response.write("
Applicant:" + StringUtils.escapeToHTML(s, 50) + ""); } ... }

Tough stuff, but I hope it was worth reading to you.
Any feedback is welcome!

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Andreas,

    This is really a very good blog giving more info about security issues related to scripting!
    I would also like to mention here about my blog regarding scripting allowed in SDN Weblogs!

    /people/sap.user72/blog/2005/09/13/potential-security-vulnerability-in-sdn-weblogs-and-other-applications-allowing-for-html-input

    I am very happy that you had clearly addressed the security issue mentioned in my blog!

    Best regards ๐Ÿ™‚
    Felix

    (0) 
  2. Former Member
    Hi Andreas,
    thank you for this very good introduction to XSS. So far I never considered the different cases you described.

    Some of us still use BSP and so it would be great to get some advice also for this technology. I don’t know if HTMLB is addressing these issues (I don’t use it much).

    There is an ABAP method CL_HTTP_UTILITY=>ESCAPE_HTML that, as far as I understand, can be used for case 1 and case 2 in BSP pages.

    Best regards,
    Christian.

    (0) 

Leave a Reply