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.


  1. 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!


    • avatar
    • 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.



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

    • avatar
    • 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.

  3. 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.

    • avatar
    • A De
    • Thu 9 Oct 2008 09:32 PM

    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

    • avatar
    • 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

    • avatar
    • 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.

    • avatar
    • Colin
    • Mon 19 Oct 2009 03:59 PM

    Hi All,

    We recently did an appscan as part of the security process at work and found a number of cross site scripting issues with our apps. Has anyone developed a strategy to reolve this issue within domino???

    Java agent or some type of coding method that does not require input validation on every field....



      • avatar
      • Jake Howlett
      • Tue 20 Oct 2009 12:58 AM

      I have just the Java agent you're looking for Colin. Drop me a line via the "Contact Us" link at the bottom and we can discuss.

  4. Hi Jake,

    As you can see it's been some time since I have been back to your site. Please send me an email if you can and let me know what resources you have avail. for XSS. We have tried several things over the months including add-on software to no avail.


    • avatar
    • Howard Jacob
    • Mon 26 Jul 2010 03:53 AM

    Hi all,

    I urgently need a xss filter in java library format for one of my projects. What do you recommend?

    In addition, is there any non-opensource type of xss filter which I can subscribe for service support?

    Thanks in advance.

  5. Hello Jake ,

    Did u worked on how we can fix the XSS for domino ,if so can u please share the database to me




    • avatar
    • Jake Howlett
    • Tue 10 Aug 2010 09:12 AM

    @Trevini. See the code example in the DEXT database which you can download from the Sandbox link above.

  6. I'm searching for resolutions to the ever present threat of XSS and have read this post. An additional "booger" is when you have users that want to include angle brackets, especially with financial data or any other where comparison is made. For example, "probably of this aware is < 100%, but >= 80%. Please advise."

    This is a common type comment made in one of our cost type applications. Unless the field is HTML, the < conversion won't work - it will take the literal '<' and display.

    Add the dual complexity of storing data and then in a view or elsewhere hyperlinking part of that data for a clickable URL to open it or whatever. I would love to hear what the latest goings on are for this.

Your Comments


About This Page

Written by Jake Howlett on Fri 26 Sep 2008

Share This Page

# ( ) '


The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social

About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »


Here are the external links posted on the same day.

More links are available in the archive »

More Content