Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSS - Which HTML Tags and Attributes can trigger Javascript Events?

Tags:

I'm trying to code a secure and lightweight white-list based HTML purifier which will use DOMDocument. In order to avoid unnecessary complexity I am willing to make the following compromises:

  • HTML comments are removed
  • script and style tags are stripped all together
  • only the child nodes of the body tag will be returned
  • all HTML attributes that can trigger Javascript events will either be validated or removed

I've been reading a lot about on XSS attacks and prevention and I hope I'm not being too naive (if I am, please let me know!) in assuming that if I follow all the rules I mentioned above, I will be safe from XSS.

The problem is I am not sure what other tags and attributes (in any [X]HTML version and/or browser versions/implementations) can trigger Javascript events, besides the default Javascript event attributes:

  • onAbort
  • onBlur
  • onChange
  • onClick
  • onDblClick
  • onDragDrop
  • onError
  • onFocus
  • onKeyDown
  • onKeyPress
  • onKeyUp
  • onLoad
  • onMouseDown
  • onMouseMove
  • onMouseOut
  • onMouseOver
  • onMouseUp
  • onMove
  • onReset
  • onResize
  • onSelect
  • onSubmit
  • onUnload

Are there any other non-default or proprietary event attributes that can trigger Javascript (or VBScript, etc...) events or code execution? I can think of href, style and action, for instance:

<a href="javascript:alert(document.location);">XSS</a> // or
<b style="width: expression(alert(document.location));">XSS</b> // or
<form action="javascript:alert(document.location);"><input type="submit" /></form>

I will probably just remove any style attributes in the HTML tags, the action and href attributes pose a bigger challenge but I think the following code is enough to make sure their value is either a relative or absolute URL and not some nasty Javascript code:

$value = $attribute->value;

if ((strpos($value, ':') !== false) && (preg_match('~^(?:(?:s?f|ht)tps?|mailto):~i', $value) == 0))
{
    $node->removeAttributeNode($attribute);
}

So, my two obvious questions are:

  1. Am I missing any tags or attributes that can trigger events?
  2. Is there any attack vector that is not covered by these rules?

After a lot of testing, pondering and researching I've come up with the following (rather simple) implementation which, appears to be immune to any XSS attack vector I could throw at it.

I highly appreciate all your valuable answers, thanks.

like image 700
Alix Axel Avatar asked Aug 07 '11 21:08

Alix Axel


People also ask

What types of HTML tags can be used to execute XSS attacks?

XSS Using Script in Attributes XSS attacks may be conducted without using <script>... </script> tags. Other tags will do exactly the same thing, for example: <body onload=alert('test1')> or other attributes like: onmouseover , onerror .

Does XSS use JavaScript?

How does Cross-site Scripting work? In a Cross-site Scripting attack (XSS), the attacker uses your vulnerable web page to deliver malicious JavaScript to your user. The user's browser executes this malicious JavaScript on the user's computer.

What is XSS in JavaScript?

Cross-site scripting (XSS) is a security exploit which allows an attacker to inject into a website malicious client-side code. This code is executed by the victims and lets the attackers bypass access controls and impersonate users.

Which HTML attribute must be used along with the a tag to make the code secure to prevent security attacks?

PMHJ prevents the injection attack of HTML elements with a random attribute value and the node-split attack by an attribute with the hash value of the HTML element.


1 Answers

You mention href and action as places javascript: URLs can appear, but you're missing the src attribute among a bunch of other URL loading attributes.

Line 399 of the OWASP Java HTMLPolicyBuilder is the definition of URL attributes in a white-listing HTML sanitizer.

private static final Set<String> URL_ATTRIBUTE_NAMES = ImmutableSet.of(
  "action", "archive", "background", "cite", "classid", "codebase", "data",
  "dsync", "formaction", "href", "icon", "longdesc", "manifest", "poster",
  "profile", "src", "usemap");

The HTML5 Index contains a summary of attribute types. It doesn't mention some conditional things like <input type=URL value=...> but if you scan that list for valid URL and friends, you should get a decent idea of what HTML5 adds. The set of HTML 4 attributes with type %URI is also informative.

Your protocol whitelist looks very similar to the OWASP sanitizer one. The addition of ftp and sftp looks innocuous enough.

A good source of security related schema info for HTML element and attributes is the Caja JSON whitelists which are used by the Caja JS HTML sanitizer.

How are you planning on rendering the resulting DOM? If you're not careful, then even if you strip out all the <script> elements, an attacker might get a buggy renderer to produce content that a browser interprets as containing a <script> element. Consider the valid HTML that does not contain a script element.

<textarea><&#47;textarea><script>alert(1337)</script></textarea>

A buggy renderer might output the contents of this as:

<textarea></textarea><script>alert(1337)</script></textarea>

which does contain a script element.

(Full disclosure: I wrote chunks of both HTML sanitizers mentioned above.)

like image 103
Mike Samuel Avatar answered Nov 15 '22 12:11

Mike Samuel