SAP Community Network Web Server WTF



  • If you have had the pleasure of working with SAP products, you will know that they all have a fair share of WTFs deep down below. Most of the errors can be explained by negligence, inexperience, malice, or maybe sheer stupidity. This bug I stumbled upon in their forum software, though, keeps dumbfounding me as for the life of me I can't figure out which major design snafu is going on right down there. OK, maybe not for the life of me, but it shows that there's something wrong on more levels I even know or care about.

    Their URL is: http://www.sdn.sap.com/irj/scn

    This is the bug description:

    Whenever you submit the name of a common client side JavaScript event handler followed by an equals sign in the search text field (or pretty much any text field, for that matter), the server crashes with the error message "Method not implemented".

    For example, try "onselect=". An "onselect" will not trigger the error, but "onselect<any_number_of_blanks>=" does. Or "onclick=", for instance. Or "onmouseover=". But not "onfubar=".

    Now I browse this site with JavaScript off, so I'm sure it has nothing to do with my client. You can also call the search URL directly: http://www.sdn.sap.com/irj/scn/advancedsearch?query=onselect+%3D

    This will also trigger the error.

    WTF is going on there, SAP. Where in the mysterious maze of that Java-powered ABAP crapfest is the server actually choking on a simple string that happens to be a JavaScript event handler name. WTF, SAP. WTF.

    I think these two acronyms will be forever linked in my brain. And for those of you who always crave for TRWTF, here is it: I told them about this bug two years ago.

    WTF, SAP. WTF.



  • Simple enough. They are trying to do some sort of server-side sanitising (removing harmful markup that could be a XSS attempt). When they detect what looks like an attempt to generate a JS event handler attribute, it tries to remove it. The removal function is relying on some method that is not implemented in that specific server-side environment, so it throws an error.



  • @TarquinWJ said:

    Simple enough. They are trying to do some sort of server-side sanitising (removing harmful markup that could be a XSS attempt). When they detect what looks like an attempt to generate a JS event handler attribute, it tries to remove it. The removal function is relying on some method that is not implemented in that specific server-side environment, so it throws an error.
     

    Which, of course, sounds a lot like the tried-and-tested SQL-injection-proofing method of replace("WHERE", "") . So, calling this a WTF is still appropiate.



  • @TarquinWJ said:

    Simple enough. They are trying to do some sort of server-side sanitising (removing harmful markup that could be a XSS attempt). When they detect what looks like an attempt to generate a JS event handler attribute, it tries to remove it. The removal function is relying on some method that is not implemented in that specific server-side environment, so it throws an error.
     

    Gee. Let me clarify. The web server crashes with error 501, "Method GET not implemented".

    And do you really think a search term like "onmouseover=" is "harmful markup" and not being able to search for it prevents XSS attacks :-) YMMD :-)

     



  • @PSWorx said:

    So, calling this a WTF is still appropiate.
    No arguments here.@cforcode said:
    The web server crashes with error 501, "Method GET not implemented".
    I don't know how they get to that stage (perhaps a nested call to the server, or perhaps the server's default reaction when a server-side script aborts is to show a 501 error).@cforcode said:
    do you really think a search term like "onmouseover=" is "harmful markup"
    Do I? No. But they do. There is a reason where it is harmful - if you are not sanitising content properly. Imagine I have a search field like this:
    <input value="" name="q">
    and when you search for something, I want to put what you searched for inside that input so you can modify it. The correct thing to do is to replace harmful characters with their entities. The stupid thing to do is to try to remove parts of my content (what this site is doing). If you search for this:
    " onmouseover="do.some.evil()" whocares="
    escaping the quotes would give this:
    <input value="&quot; onmouseover=&quot;do.some.evil()&quot; whocares=&quot;" name="q">
    If you just remove the onmouseover= (like this site is trying and failing to do), you get:
    <input value="" "do.some.evil()" whocares="" name="q">
    Some broken markup. A naïve Web dev would assume that is safe, though it is easy enough to break simply by making the removal result in the same injection code as before:
    oonmouseover=nmouseover=
    Or whatever vector works for their specific removal approach.



  • @TarquinWJ: This has nothing to do with sanitizing input. This bug occurs on an entirely unrelated level, and that's the WTF.

     



  • @cforcode said:

    This has nothing to do with sanitizing input.
    I don't see what else it could be. They are trying to protect against common script injection approaches. The result is a little unusual (normally you would expect a server-side script error message, not a server error message, if it was implemented in the server-side script code), but there are enough ways to get a server side error message instead. From most languages, for example, you could set the response code to 501 if you saw something you didn't like - a stupid approach to protecting but it's almost certainly being used by some deluded Web dev. Then there's also Apache's mod_security which produces errors exactly like this when it sees something it thinks is a XSS attempt. I'd vote for this being mod_security, since it is most likely to be XSS protection implemented at the server level, rather than the server-side-scripting level. Either way the approach is stupid since it faces the user with nonsense when they make legitimate requests.



  • First, this isn't Apache or any other web application server you know. This is a SAP enterprise product (they eat their own dog food and choke on it sometimes).

    Second, if this problem was due to sanitation, they would have discovered it during testing, right? So either they don't test (=> WTF) or their QA allows this to happen (=> WTF). This is both very unlikely.

    Third, setting an HTTP response code 501 as the result of an input sanitation is like, well, blowing up the house if somebody presses the door bell button for an empty apartment. It is very unlikely that this behaviour is by design.

    So, the only logical consequence is that this error occurs right in the bowels of their web server as the result of a convoluted maze of twisted code paths through a dozen crappy abstraction layers piled onto each other in a rickety rube-goldbergian way. I have seen this code, and I know what I'm talking about.



  • @cforcode said:

    So, the only logical consequence is that this error occurs right in the bowels of their web server as the result of a convoluted maze of twisted code paths through a dozen crappy abstraction layers piled onto each other in a rickety rube-goldbergian way. I have seen this code, and I know what I'm talking about.

    That's always been my impression of how everything gets done in SAP, so you're probably right.



  • Since it also happens with completely different parameters on completely different paths on the server, like http://www.sdn.sap.com/the/daily/wtf?xss=onclick=, I'd say it is mod_security or any other similar "web application firewall". You can add any amount of non-letters between the onclick and the = and it will still trigger. Other typical patterns like <script work as well. And the QA team is most likely aware of it.

    • Big customer wants to have a guarantee that the following list of attributes and/or tags are never reflected by a reflected xss attack.
    • Big customer wants to audit the code or have someone else audit it, for $BIGNUM per LOC.
    • SAP does not want to lose big customer
    • SAP wants to spend as little money as possible
    Result: They implement a module in the webserver (or buy an off-the-shelf WAF) that has the builtin blacklist and checks every query parameter for them. If found, print a simple error message (and that error message is even friendlier than most messages I've seen in scenarios like this, like "500 ." with an empty body...). That code is easy to audit, and since the tag can never get into the webserver, it can never be reflected. Customers are happy, (except those that try to search for that parameter of course), and QA just has to ignore issues ("yes, we know, but we are 'secure' now") that contain this parameter anywhere.

    I've been involved enough with so-called PCI-DSS compliance audits, and usually hacks like this will be employed there since companies try to save money but get the certification nonetheless...

    You don't have to tell me that this behavior is as useless and error prone as personal firewalls, antivirus software, etc. But people (not only SAP) are using it because some compliance criteria say it is enough to be compliant.



  •  An interesting analysis. Thanks.



  • Also, for mihi's test run, the response headers are:

    HTTP/1.1 501 Method Not Implemented
    Date: Sun, 03 Jul 2011 16:05:44 GMT
    Server: Apache
    Allow: 
    Content-Length: 218
    Connection: close
    Content-Type: text/html; charset=iso-8859-1
    Set-Cookie: SDNSTATE=476319916.14340.0000; path=/

    Looks like Apache to me.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.