My favorites | Sign in
Project Logo
             
Search
for
Updated Nov 15, 2008 by pilgrim
Labels: is-article, about-security
ArticleXSSInEventHandlers  
HOWTO filter user input in JavaScript event handlers

Español日本語Français
HomeWeb Security

In addition to all the ways to inject malicious script in <script> tags, there is an additional complication that arises for JavaScript in event handlers. (By "event handlers," I mean JavaScript-valued tag attributes such as onclick, onload, or onerror.) The values of such attributes are HTML-unescaped before they are passed to the JS interpreter.

Example

For instance, consider the template snippet

  <form:button ...
               onclick='GotoUrl("%(targetUrl)s");'>

Suppose an attacker injects the value

Why? Because the browser HTML-unescapes the value of the onclick attribute automatically. The expression that is actually evaluated by the browser's JS interpreter is this:

  GotoUrl("foo");evil_script("");

So the JavaScript interpreter will end up executing evil_script.

How to Avoid

If you must insert dynamic string literals into the context of an attribute that is interpreted as a JavaScript expression (such as onclick, onload, onerror, or a myriad of others),

  1. ensure that the string literal is JavaScript-escaped using a function that satisfies the criteria defined for JavaScript context
  2. ensure that the string literal is enclosed in single quotes
  3. HTML-escape the surrounding attribute value
  4. ensure that the surrounding attribute value is enclosed in double quotes

(Order of operation is important here! Escape in this exact order!)

As an additional safety measure, your JS-escape function should also escape the five HTML metacharacters &, <, >, ", and ' into their corresponding hexadecimal or Unicode JavaScript character escapes.

Rationale

The additional HTML-escaping step ensures that the JS expression passed to the JS interpreter is as intended, and an attacker cannot "sneak-in" HTML encoded characters.

Using different style quotes for JS literals and the attribute provides a safety measure against one type of quote accidentally "ending" the other.

The use of a JS-escaping function that escapes HTML metacharacters into numeric JS-string-escapes provides an additional safety measure in cases where a programmer forgets to use both escapings in sequence and only uses the JS escape. Note that for this measure to be effective, it is important to use the numeric escape for quote characters (i.e. \x22 instead of \"), since the HTML parser doesn't consider the backslash an escape character, and therefore a non-HTML-escaped \" would actually "end" the attribute.

Further reading


Sign in to add a comment
Hosted by Google Code