Last year Jeff Williams and I discovered 2 critical flaws in SiteMinder. Rather than just sitting on the flaws or leaving the client to report them, we decided to experiment with responsible disclosure with the company who manages SiteMinder, Computer Associates (CA). The process was painfully slow and from our perspective a little disrespectful. For months they kept asking for details about the product version and configuration – details that we told them we didn’t know and couldn’t provide without being a major annoyance to our customers. We repeated ourselves and kept pressing for them to fix it.

We repeatedly asked for status, considering the fixes should be relatively easy and we got very little information until now. The timelines in the responsible disclosure guidelines by Wysopal & Christey were obliterated by CA. We just got an email after months saying they just tested their latest build (something we suggested they do on day one) and that the attacks appear not to work anymore.

This response, after thinking a bit, seems like an insult to my intelligence. The attacks haven’t not worked on any SiteMinder-protected application we’ve tested since last year. All of a sudden they decide it’s important and test their latest build and it no longer works? Apply some critical thinking skills and ask yourself what is more likely:

  • They randomly fixed both of these vulnerabilities before we reported it. Keep in mind the following facts:
    • We are seeing them work in the wild 24/7
    • There are no advisories regarding these vulnerabilities on their advisory blog
    • It took 6 months for them to “get around” to testing our 2 newly reported critical vulnerabilities
    • or…
  • They took our information, spent the last 6 months fixing the vulnerabilities quietly, and now have plausible deniability

So much for responsible disclosure.

The motivation for researchers to find flaws is credit. Credit is the currency we deal in. As gaz pointed out on Twitter, “bug hunting is fun”, but at the same time bug hunters are also providing an extremely valuable service and should be compensated in some way for the bugs they find. Credit to the researchers in a patch or advisory is the only currency that vendors have been willing to pay, especially for layer 7 bugs. You think ZDI’s paying me for my XSS?

So, since the bugs have been “fixed” we can now talk about them, right?

What is SiteMinder?
SiteMinder, for the uninitiated, is a  security gateway that sits in front of 80-90% of corporate America’s J2EE applications. It’s used to provide authentication, URL authorization and XSS protection on GET requests.

Although it’s used to protect J2EE applications, SiteMinder itself is written in an unmanaged language.

Flaw #1: Complete XSS-defense Bypass Through Null-Byte Injection
Normally, passing almost any special characters in a GET request to SiteMinder will cause an error to occur. It’s practically impossible to XSS a SiteMinder application through a GET because of this. The user data must land inside a JavaScript context, unquoted attribute, or some other unusual scenario for exploitation to be possible. Passing data in via a POST is the low-tech way to do this, but it’s not ideal for reflected XSS.

Jeff was testing this mechanism and he tried prepending his payload with %00. SiteMinder didn’t see the attack because it recognized %00 as the end-of-string character. Here’s some text from our disclosure to them:

The following URL, which attempts to exploit a non-existent XSS vulnerability in the a page will be caught by Siteminder’s XSS protection:

http://victim/app/function?foo=bar<script>alert(document.cookie)</script>

However, prepending the parameter value with a null byte directly will cause the parameter value to go unnoticed by the protection mechanism, as can be seen in the following URL:

http://victim/app/function?foo=bar%00<script>alert(document.cookie)</script>

This indicates that the code for parsing parameters is done in an unmanaged language like C or C++ and interprets the null-byte as the end of string character. Unfortunately, Java considers the null byte just another part of the string, so what comes after it is used in the vulnerable page and the reflected XSS will be fired.

Flaw #2: Complete XSS-defense Bypass Through Canonically Decomposable (aka “overlong”) Unicode
This one we anticipated would be harder to fix since it would require some architectural re-thinking. By passing an “overlong” version of a SiteMinder-blacklisted character (like %e0%80%bc for ‘<’) you could get the attack to pass SiteMinder’s check, which obviously worked at the byte or ASCII-character level. However, when the J2EE application server got a hold of the multi-byte character sequence it canonicalized the data into Unicode (Java uses UTF-16 under the hood). Here is some text from our disclosure to them:

There are a multitude of issues when interpreting UTF-8 in a gateway security mechanism. Invalid UTF-8 of all forms, including overlong UTF-8, using best-fit mappings and performing normalization can all cause problems. The following URL will be caught by SiteMinder because it contains a ‘<’.

http://victim/app/function?foo=bar<

However, passing the following URL will not trip the protection mechanism:

http://victim/app/function?foo=bar%e0%80%bc

The seemingly random assortment of bytes (0xe080bc) is reduced to the ‘<’ character when its consumed into a Java String object because the JavaVM understands and reduces this inappropriately long representation of a UTF-8 character. Strictly looking for the 0x3C byte to detect ‘<’ characters will always fail because of this, so the SiteMinder protection needs to be Unicode aware. These issues are presented well in the Unicode technical report #36: http://unicode.org/reports/tr36/, specifically in section 3.

Summary
That’s our story. At the end of the day, we didn’t get credit from CA, but our bugs supposedly got fixed, so we’ll call it a push.

P.S. Anyone interested in finding a more vulnerabilities in SiteMinder should try to use these techniques in different areas. For instance, sending in a canonically decomposable version of an entire URL may prevent any SiteMinder rules from matching, and in those cases where the default resource setting is “UNPROTECTED”, this may amount to a complete authentication and/or authorization bypass. The null byte may be also used in other avenues, but you won’t be hearing about any more flaws I find. =)