Skip Navigation
Details
Author: Jake Howlett
Date: Fri 26 Sep 2008

Permalink

Comments / Add / Subscribe

« Hacking Domino: XSS-Safe Form - Can You Hack It? | Blogs | Hacking Domino: Harvesting Your User's Logins -- Why You Should Take XSS Seriously! »

Hacking Domino: How to Filter Out XSS Attacks

Hopefully by now I've convinced you to take XSS seriously?! If so then you're probably keen to see what the solution is. Let's see shall we.

The basic premise is that all field values submitted as part of your Domino web forms must be inspected for any potential attacks. And I mean all fields. As I showed on Wednesday even hidden and/or computed fields could be vulnerable.

How you filter the field depends on its type. For normal Text fields where you don't expect or want HTML then you need to remove all HTML. This is just a case of replacing all angle brackets (< or >) with either &lt; or &gt;. Job done. For fields where you want to allow HTML entry it gets a whole lot more complicated.

You can either use a "tag whitelist" or "tag blacklist" of HTML tags you either want to allow or remove, respectively. It's probably easier to maintain a whitelist, which might include the following subset of HTML tags:

a, b, blockquote, br, caption, center, col, colgroup, comment, em, font, h3, h4, h5, h6, hr, img, li, ol, p, pre, s, small, span, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul

If you do decide to use a blacklist then here's a taster of the kind of thing to look out for. All of these tags can be used in malice:

link, iframe, frame, frameset, object, param, embed, style, applet, meta, layer, import, xml, script, base

Once you've removed/replaced all the tags you don't want (while deciding what to do with their content) you then have to look at the inner attributes of the tags that remain.  Here's a sample of a "attribute whitelist".

abbr, align, alt, background, bgcolor, border, cellpadding, cellspacing, cite, clear, color, cols, direction, face, font-weight, headers, height, href, hspace, leftpadding, loop, noshade, nowrap, point-size, rightpadding, rowspan, size, span, src, summary, target, title, toppadding, type, valign, value, vspace, width, wrap

If you use a blacklist then you need to look for any event-related attribute such as onclick, onmouseover etc. All of which can do considerable harm.

Nothing is ever easy though is it. Even if you've removed the potentially naughty attributes the actual value of the normally safe ones can in turn cause harm. Consider a user entering the following HTML:

<img style="xss:expr/*XSS*/ession(alert('XSS'))">

Both the tag and the attribute are in our whitelists so it might get past the filter on the first pass. Howeve, in IE, this innocent-looking bit of HTML can execute JavaScript code.

For all the attributes you do allow you need to examine their actual values for naughty code. In the example above it's not even as simple as looking for the word "expression" in the value. You first need to strip it of comments and whitespace and make sure your search isn't case-sensitive. It all gets very complicated. Take a look at this extensive list of possible hacks to see just what we're dealing with.

As yet I've not finished work on the code for the filter needed to prevent XSS attacks. Even when I do I don't know if I'd be willing to bet money on it being 100% effective and don't even know if there's a filter out there that is.

What has surprised me is that there doesn't seem to be an existing Java library that will take a String input of HTML and make it safe (while formatting it and correcting errors). You can bet Ruby on Rails and PHP have effective filters, but I just can't find the Java equivalent. While I work on rectifying that you'll just have to wait. I hope you're not a sitting duck in the mean time ;o)

I'm keen to get it done as I'm well aware I need to apply the code in more than a few places on this server!

When I'm happy with the code I'll make it available for testing/download and describe the approach I've taken to implementing its use in Domino in more detail.

Comments

Devin Olson (Fri 26 Sep 2008 11:54 AM) website / e-mail

Hey there Jake. I've followed this entire series (lurk mode); and I've very much enjoyed it.

I was doing some testing, and even simple things like onmouseover="my malicious script" can get through without careful checking.

For normal (where HTML is not allowed) fields, the following input translation formula works very well:

@ReplaceSubstring(@Trim(@ThisValue); "<":">"; "&lt;":"&gt;");

For fields where HTML IS allowed, I think the blacklist approach would ultimately prove unworkable. I think a whitelist approach is a much better idea.

Anyway, thanks for posting this very helpful series!

-Devin.

Akash D. (Fri 26 Sep 2008 11:56 AM)

Will you run into same issue if the login page is from Juniper and then Juniper can authenticate with Domino?

We use Juniper for external client authentication, juniper in turn will authenticate with domino server. Login in successfully the user is directed to home page.

Thanks

Akash

mdmadph (Fri 26 Sep 2008 01:55 PM) website / e-mail

That one XSS attack you mention that works in the "style" param in IE -- is that just IE6? Or is IE7 afflicted, too?

Jake Howlett (Fri 26 Sep 2008 02:17 PM)

Devin. Glad you like it. I agree the whitelist approach is best.

mdmalph. According to the list at Link it "works" in IE7 too.

Per Henrik Lausten (Sat 27 Sep 2008 01:18 PM) website / e-mail

Jake, great work (as usual). I was looking for practical examples some time last year and did not really find anything useful. I needed the examples for a Domino web site with potential XSS vulnerabilities.

A De (Thu 9 Oct 2008 09:32 PM) e-mail

I've used the htmlawed PHP filter for XSS checks; it allows mixed white- and black-list approaches.

See bioinformatics.org/phplabware/internal_utilities/htmLawed/index.php and bioinformatics.org/phplabware/internal_utilities/htmLawed/rsnake/RSnakeXSSTest.htm

madwhite hatter (Tue 14 Oct 2008 02:20 PM)

I am using this simple bit of code, though it probaby needs more.

Public Function HTMLEncodeXSS(dirtyString As String) As String

Dim cleanString As Variant

Dim vOriginal(0) As String

Dim vFind(6) As String

Dim vReplace(6) As String

' scrub xss vulnerabilites

vOriginal(0) = dirtyString

vFind(0) = {<}

vFind(1) = {>}

vFind(2) = {%3c}

vFind(3) = {%3e}

vFind(4) = {"}

vFind(5) = {'}

vFind(6) = {\}

vReplace(0) = {&lt;}

vReplace(1) = {&gt;}

vReplace(2) = {&lt;}

vReplace(3) = {&gt;}

vReplace(4) = {&quot;;}

vReplace(5) = {&#039}

vReplace(6) = {&#092}

cleanString = Replace(vOriginal, vFind, vReplace)

HTMLEncodeXSS = cleanString(0)

End Function

Jake Howlett (Wed 15 Oct 2008 07:33 AM)

That's all very well madwhite but only works on fields where you don't want any HTML.What about fields where you do want to allow HTML to be entered? That's what I'm trying to deal with here with the tag whitelist.

Add your response here:

Name *:
E-mail:
Protected from spambots!
Website:
rel="nofollow"

Comment *:
HTML is not allowed!

Note: This blog entry is more than two weeks old so your comment, as an anti-spam measure, will be sent for approval.