salesforce / secure-filters

Anti-XSS Security Filters for EJS and More
BSD 3-Clause "New" or "Revised" License
139 stars 39 forks source link

Handle mXSS #6

Open amalkrishnancg opened 10 years ago

amalkrishnancg commented 10 years ago

"m-XSS vectors bypassed widely deployed server-side XSS protection techniques (like HTML Purifier, kses, htmlLawed, Blueprint and Google Caja), client-side filters (XSS Auditor, IE XSS Filter), Web Application Firewall (WAF) systems, as well as Intrusion Detection and Intrusion Prevention Systems (IDS/IPS)" https://cure53.de/fp170.pdf

This should be interesting.

stash commented 10 years ago

"Mutation-based XSS (mXSS) makes an impact on all three major browser families (IE, Firefox, Chrome)."

"A web application is vulnerable if it inserts user-contributed input with the help of innerHTML or related properties into the DOM of the browser."

So, basically, DOM-based XSS. I'm not sure if that fits in with this module, which is specifically targeting server-side templates.

stash commented 10 years ago

This novel class of attack vectors utilize performance-enhancement peculiarities present in all major browsers, which mutate a given HTML string before it is rendered. We propose the term mXSS (for Mutation-based XSS) to describe this class of attacks to disambiguate and distinguish them from classic, re ected, persistent and DOM-based XSS attacks.

amalkrishnancg commented 10 years ago

"Note that problems such as the backtick-mutation still affect the HTMLPurifier as well as Blueprint and Google Caja; they haveonly just been addressed successfully by the OWASP Java HTML Sanitizer Project 4"

"The class of mXSS attacks poses a major challenge for server-side XSS filters. To completely mitigate these at- tacks, they would have to simulate the mutation effects of the three major browser families in hopes of determining whether a given string may be an mXSS vector."

stash commented 10 years ago

Oh, here's one test vector we need to protect against:

<!-- Attacker Input -->
<img src="test.jpg" alt="``onload=xss()" />
<!-- Browser Output -->
<IMG alt=``onload=xss() src="test.jpg">
amalkrishnancg commented 10 years ago

The good old backtick trick :)

stash commented 10 years ago

:) this is going to be fun

amalkrishnancg commented 10 years ago

Mario's slides: https://www.hackinparis.com/talk-mario-heiderich

@gheldsf

stash commented 10 years ago

Great slides. Any pointers to effective solutions, or is an answer simply "don't use .innerHTML"?

amalkrishnancg commented 10 years ago

I'm still going through the white paper. I'll let you know after I finish the Defenses section.

On Tue, Oct 15, 2013 at 2:51 PM, Jeremy Stashewsky <notifications@github.com

wrote:

Great slides. Any pointers to effective solutions, or is an answer simply "don't use .innerHTML"?

— Reply to this email directly or view it on GitHubhttps://github.com/goinstant/secure-filters/issues/6#issuecomment-26375637 .

amalkrishnancg commented 10 years ago

We should take a look at what OWASP Java HTML Sanitizer Project is doing since it was mentioned in the paper.

amalkrishnancg commented 10 years ago

"The fixes applied to HTML sanitizers, as mentioned in the introduction, are new rules for known mutation effects. It can be seen as a challenging task to develop new filtering paradigms that may discover even unknown attack vectors."

The paper discusses some client side mitigation strategies too, but it's very limited.

stash commented 10 years ago

Re the Java Sanitizer, i was able to find this test: https://code.google.com/p/owasp-java-html-sanitizer/source/browse/trunk/src/tests/org/owasp/html/HtmlSanitizerTest.java#264 - note the space added at the end

  @Test
  public static final void testInnerHTMLIE8() throws Exception {
    // Apparently, in quirks mode, IE8 does a poor job producing innerHTML
    // values.  Given
    //     <div attr="``foo=bar">
    // we encode &#96; but if JavaScript does:
    //    nodeA.innerHTML = nodeB.innerHTML;
    // and nodeB contains the DIV above, then IE8 will produce
    //     <div attr=``foo=bar>
    // as the value of nodeB.innerHTML and assign it to nodeA.
    // IE8's HTML parser treats `` as a blank attribute value and foo=bar
    // becomes a separate attribute.
    // Adding a space at the end of the attribute prevents this by forcing
    // IE8 to put double quotes around the attribute when computing
    // nodeB.innerHTML.
    assertEquals(
        "<div title=\"&#96;&#96;onmouseover&#61;alert(1337) \"></div>",
        sanitize("<div title=\"``onmouseover=alert(1337)\">"));
  }