Tag Archives: csrf

#HackerKast 29 Bonus Round: Formaction Scriptless Attack

Today on HackerKast, Matt and I discussed something called a Formaction Scriptless Attack. Content Security Policy (CSP) has put a big theoretical dent in cross site scripting. I say theoretical because relatively few sites are taking advantage of it yet; but even if it is implemented to prevent JavaScript from loading on the page, that doesn’t necessarily remove the possibility of attack from HTML injection.

For example, let’s say you have a site that has CSP set up to prevent inline and remote JavaScript from loading using the nonce feature, which requires all script tags to include the nonce before they will load. The nonce is probably based on some locally known secret XOR’d with the user’s credential or something similar. Whatever the case the CSP nonce is not known. But what they really want to do is submit some form. Now the form itself might protect itself in a different way, using a server-generated nonce (a second one) to prevent cross site request forgeries. Barring any side channel attacks, MitM attacks or attacks against the server itself, it seems like this might stop you in your tracks.

HTML5 to the rescue! Let’s say the form has an id set of id=”form1″. HTML5 has a feature where any input field anywhere on the page (yes, even outside of the form block) can say that it belongs to any form using the “form” parameter (e.g. form=”form1”). That might be somewhat bad, because perhaps I can include an extra form field and make the user do something they didn’t mean to do. But worse yet, HTML5 also has a feature called formaction. Formaction allows me to change the location where the form is being submitted.

So if the attacker submits an input field that associates itself with the form that contains the secret nonce and also with the formaction directive which points the form to the attacker’s website, it’s pretty much game over if the user clicks on that button. So now the trick is to get the attacker to click on the button. Oh, if only there was a way to get people to click on arbitrary places on a page from another domain… oh wait! Clickjacking!

So if the site is using CSP but not using X-Frame-Options or similar techniques to prevent the site from being framed, the attacker can frame the page and force the user to click on the evil button that has set a formaction which points the form back to the attacker’s site. The attacker then takes that nonce, creates a page that automatically uses the nonces and forces a CSRF request with the secret nonce. So much for CSRF protection! Here is the original vulnerable page and here is the clickjacked version of it with semi-opacity enabled to make it easier to see (tested in Firefox only).

Scriptless attacks aren’t new, Mario Heiderich for example has been working on them for years, but they are deadly. It’s not quite the same thing as a cross domain read in this case, but it has the same effect – allowing the attacker to read information from the target domain for use in an attack. I highly recommend using X-Frame-Options on all your pages. But that only stops one form of the attack. It’s still possible to social engineer people and so on. Why devs need to associate input fields with forms outside of the form block is still a bit of a mystery to me and why they need to change the form action after the fact — even overriding the original location — is also a puzzle. But with every new feature comes a new way to abuse it. HTML5 is an interesting beast, that’s for sure!

Update: As mentioned on Twitter, you can use CSP to block formaction, but you have to do that or the attack will still work with other CSP rules. Also you can do the equivalent of X-Frame-Options in CSP as well. So a properly configured CSP might actually save you – very cool!

Raising the CSRF Bar

For years, we at WhiteHat have been recommending Tokenization as the number one protection from Cross Site Request Forgery (CSRF). Just having a token is not enough, of course, as it must be cryptographically strong, significantly random, and properly validated on the server. Can’t stress that last point enough as the first thing I try when I see a CSRF token is to empty the value out and see if the form submit is accepted as valid.

Historically the bar for “good enough” when it comes to CSRF tokens was if the token was changed at least per session.

For example: A user logs in and a token is generated & attached to their authenticated session. That token is used for that user for all sensitive/administrative forms that are to be protected against CSRF. As long as when the user is logged out and logged back in they received a new token and the old one was invalidated, that met the bar for “good enough.”

Not anymore.

Thanks to some fellow security researchers who are much smarter than I when it comes to crypto chops, (Angelo Prado, Neal Harris, and Yoel Gluck), and their latest attack on SSL (which they dubbed BREACH), that no longer suffices.

BREACH is an attack on HTTP Response compression algorithms, like gzip, which are very popular. Make your giant HTTP responses smaller, which makes them faster for your user? No brainer. Well now, thanks to the BREACH attack, within around 1000 requests an attacker can pull sensitive SSL-encrypted information from HTTP Responses — sensitive information such as… CSRF Tokens!

The bar must be raised. We now no longer allow Tokens to stay the same for an entire session if response compression is enabled. In order to combat this, CSRF Tokens need to be generated for every request/response. This way they can not be stolen by making 1000 requests against a consistent token.


  • Old “good enough” – CSRF Tokens unique per session
  • BREACH (BlackHat 2013)
  • New “good enough” – CSRF Tokens must be unique per request if HTTP Response compression is being used.

Chained Exploits

Sometimes it is one vulnerability that gets exploited that leads to the newsworthy stories of businesses getting compromised, but usually it is the chaining of 2, 3, 4, or more vulnerabilities together that leads to the compromise of a business.

That’s where WhiteHat comes in. WhiteHat will report not just the XSS, SQL injection, and CSRF, but the Information Leakage, Fingerprinting, and other vulnerabilities. Those vulnerabilities may not be much by themselves, but if I see your dev and QA environments in commented-out HTML source code in your production environment, I just found myself new targets. That QA environment may or may not have the same code that is running on the production environment, but does it have the same configurations? The same firewall settings? Are those log files monitored like the production environment? I now have a leg up in to your network all because of an Information Leakage vulnerability that I was able to leverage and chain together with other vulnerabilities. How about a Fingerprinting vulnerability that tells me you are running an out-of-date version of nginx or PHP or Ruby on Rails. A version I happen to know is vulnerable to Remote Code Execution, Buffer Overflow, Denial of Service, or something else. You just made my job much easier. Doesn’t seem so benign now, does it?

But let’s assume for a moment that you take care of those problems. You turn off stack traces, you get rid of private IP addresses in the response headers. What next? Let’s build another scenario, one that I encountered recently.

There is a financial institution that provides online statements to users for their accounts. To encourage users to use the online statements instead of paper statements, you charge users a nominal fee to get paper versions of their imaged checks. As part of the log in process, in addition to the username and password, a user needs to answer one or more security questions before gaining access to the account. This helps prove that it is the user and not someone who was able to obtain or guess the username and password set.

Have that vision in your head? Now, what if I told you that I could CSRF transferring funds, but only between the accounts you have, perhaps a checking account and a credit card account. That surely can’t be bad, can it? Well, it turns out that the user gets charged whenever a cash advance is made from their credit card to their checking account. Okay, so I can rack up some charges. But what if I want to do something else? Say, CSRF changing their username? If you’ll recall, I need the password too, along with security questions. No go on the password and security questions. But I can CSRF changing the user from online statements to paper statements and for added fun, make them get charges for the imaged checks. My fun doesn’t stop there. The creme de la creme. The piece de resistance. The go big or go home. CSRF on the mailing address.

Why is that such a big deal, you ask? Now I know the username of the account. I have active account statements sent to a mailing address I control, along with imaged checks. And then, all I need to do is call the bank’s customer support, ask about “my” account, using “my” username, “my” account number, and the details of the imaged checks just in case the bank asks for further confirmation to prove that I am who I say I am.

And then I say: “Oh, and I’m calling because I forgot both my password and the answer to my security questions.”

Is it common for users to forget their security questions? Yes. I used to be in the habit of providing fake information to the security questions because I didn’t want an attacker who may know or guess the answer, what would otherwise be a correct answer, to my security questions. But me being me, I forgot them and I lost access to the account. Others may be in the same habit.

So you gotta ask yourself, what’s one vulnerability?

CSRF Prevention in Java

What is it and why should I care?
Cross-Site Request Forgery (CSRF) is an attack where victims are forced to execute unknown and/or undesired requests onto a website where those requests are currently authenticated. CSRF exploits the fact that the “credentials” needed to perform a function on a website are generally loaded into a client-side cookie, which is then automatically transmitted with every request. By exploiting this automatic transmission, an attacker can cause a victim to execute almost any request that is not protected against CSRF.

Below is a simple image that shows how a basic CSRF attack works:

The steps are:
Step 1. The victim is lured into visiting an evil site (evil.com)
Step 2. The victim’s browser loads the evil site, which contains a hidden image whose src points to an important transaction (on good.com)
Step 3. The victim’s browser executes the transaction at good.com, thus passing along the session cookie (general authn/z mechanism)
Step 4. The transaction occurs, but the victim is unaware until later – or perhaps never − that the transaction occurred



What should I do about this possibility?
Now that we know what CSRF is, and why it is so dangerous, let’s consider some possible solutions:

The classic solution to CSRF has been a per-session token (known as the synchronizer token design pattern).

The basic flow using this solution is:
Step 1. When the user logs in, a randomized string (token) is then placed in the user session
Step 2. On every form for a non-idempotent request (essentially meaning any request that changes the server-side state – which should be your HTTP POSTs), the token is placed in the form when it is submitted
Step 3. The request handler for the non-idempotent request validates that the submitted token matches the token stored in the session. If either of the tokens is missing, or if they do not match, do not process the transaction

In the past, this per-session token solution has served pretty well for most CSRF situations, but it can be time-consuming to implement and it also creates opportunities for forgetting validation on some requests.

Another solution that uses the token pattern is the ESAPI project, which has built-in CSRF protection, However, ESAPI’s CSRF solution is tied to the authentication scheme. Here is a write-up about using ESAPI’s CSRF protection.

A very good option offering solid protection against CSRF is the OWASP CSRFGuard project. This library makes it relatively easy to build CSRF protection into your application by simply mapping a filter and updating a configuration file. This is certainly a resource worth checking out.

Stateless CSRF Protection
One more thing I’d like to share is some interesting work in the area of stateless CSRF protection. When you cannot – or do not want to – maintain the user token in the server-side session state, this is a seemingly novel solution. The idea is to allow the client side to create a cookie with the CSRF token (which is then submitted on every request), and to then include the token as a request parameter. Because an attacker can not read both the cookie and the request parameter, then all the server side should have to do is validate that the token in the cookie and the request parameter match on another. This solution, to my knowledge, has yet to be widely reviewed or tested, but it is a great example of an elegant solution to a difficult problem. Only time will tell if this is the go-forward solution for stateless CSRF protection.

CSRF is a definitely a popular and dangerous attack, but with the protections described above, it is certainly manageable.

One last note: The token approach (classic or stateless) will break down when the site on which it is deployed contains XSS (Cross-Site Scripting) vulnerabilities. If attackers can XSS your site, they can read the content and extract the token you are using; this will effectively nullify the protection you have established. The lesson is simple: Fix those XSS bugs, too!


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>


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


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”>

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>


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


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”>

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.

WhiteHat Security’s Approach to Detecting Cross-Site Request Forgery (CSRF)

Cross-Site Request Forgery (CSRF) generates many questions from prospects, customers, partners, and Web application security professionals we work with. The questions tend to fall into similar categories, so we figured it would be helpful to summarize them and share our perspective on CSRF. We would definitely appreciate feedback and/or debate from the community to help battle-test our approach.

The 5 Most Often Asked Questions about CSRF

What is CSRF?

How do we decide which CSRF to report?

How do software security tools find CSRF today?

How do we test for CSRF?

Why do we consider CSRF unresolved if there are XSS or HTTP Response Splitting vulnerabilities present in the website?


First, what is CSRF?

At a high level, CSRF means an attacker can force a victim’s Web browser to make a request to a website of the attacker’s choosing, but the victim’s own Web browser makes the request. Of course, the ability of one’s own Web browser to make transparent requests to multiple websites is a fundamental design principle of the Web. For example, iFrames and Web 2.0 widgets perform legitimate actions like CSRF on websites all the time. The simplest form of CSRF is to embed content in one domain from another domain in a frame, which forces users’ browsers to make off-domain requests they may not realize they’re making. Another legitimate form of CSRF is to make a javascript-driven request to another website. In early Internet days many sites combined the use of frames and CSRF to share URL parameters between sites. I call this “The poor man’s Web service.”

Obviously there is potential for abuse when an attacker can make victims request a resource they want to avoid requesting, such as installing malware, changing a password to an attacker-controlled value, bidding on an unwanted item, etc. However, as noted above, there are legitimate uses for CSRF,  including pulling in off-domain “Web 2.0″ JavaScript widgets, and sourcing in an image.

Basically, CSRF has a legitimate use-case to access almost every resource − from pages to forms − on most websites. Yet from a security perspective we are only interested in the abuse-cases.

So how do we distinguish between the legitimate use-cases and the abuse-cases for CSRF?


How does WhiteHat Security decide which CSRF to report?

At WhiteHat we define CSRF as a vulnerability when an attacker can execute CSRF against any of three types of resources:

1.  Where security decisions are made.

2.  Where an attacker can use CSRF to force arbitrary code injection that impacts one or more users.

3.  Where a transaction occurs involving the transfer of money or goods.


Examples of decision-making processes that compromise security include:

  • Password Reset / User Account modification − authorization (Auth/Z) decision bypassed
  • Add contact or “friend” − confidentiality compromise based on assumption of user Auth/Z

Examples of CSRF forcing arbitrary code injection:

  • Send contact Web-based IM / message including an attack such as Cross-Site Scripting – compromise of authorization and confidentiality
  • Force user to malware/DbD  (Drive-by Download) resource or revenue-cookie-stuffing resource – again compromise of confidentiality and Auth/Z

Examples of compromised transaction processes:

  • Bid on, or purchase of, unwanted/unexpected item
  • Change the “Ship To:” address field during legitimate user purchase
  • Submit stock trading requests, front-run user decisions, or manipulate the market


Compared to most design flaws, CSRF typically has a larger subjective “grey area” when defining which CSRF are vulnerabilities. We often find that a CSRF flaw requires more explanation in order for businesses to understand how CSRF puts their websites at risk compared to other design weaknesses. Consequently, the above definitions help us focus on – and give customers an understanding of – the CSRFs that can have negative impact on their security and their business.


How do software security tools find CSRF today?

CSRF is clearly a “Design Flaw / Business Logic” vulnerability or, from a software perspective, an error of omission at specification time. Specifications that address security abuse-cases are commonly omitted – in the password-reset CSRF example we provide below – the missing specification is “only authenticatedEntity actors should be able to reset their own passwords.” Given the context of omission – and given DAST’s strength at finding errors of omission – CSRF is most easily identified by Dynamic Analysis Software Testing (DAST). While it is possible to identify weak design-patterns in source code, such as the password-reset example, we find in practice that the majority of dangerous CSRFs are not identified by either Static Analysis Software Testing (SAST) or human source-code reviews.

It appears DAST Web application vulnerability scanners approach CSRF in one of three ways:

1. False-Negatives (FN): Do not test for CSRF.

2. False-Positives (FP): After scanning a website for vulnerabilities, attempt to replay every request reporting all successfully replayed requests – both idempotent and non-idempotent − as “Potential CSRF” regardless of security impact.

3. False-Negatives + False-Positives: Attempt to replay all non-idempotent POST requests/forms, and flag all successful replays as “CSRF Vulnerabilities.”

There are two big problems with approaching CSRF-testing automation in the three ways listed above. First, the problem of false negatives: Obviously, the scanners that ignore CSRF generate FNs. However, we have observed that most scanners tend to ignore both dynamically created forms and JSON requests (GET and POST) in their CSRF results. We are uncertain whether this oversight is an attempt to reduce false-positives (many JSON requests will have no CSRF security implications) or simply an artifact of current scanner limitations in executing javascript and/or testing DOM-based forms that require user interaction. Possibly, both factors result in the presence of false negatives.

The second important FN gap is that scanners fail to identify CSRFs that facilitate arbitrary code execution. This is particularly a problem in the case of persistent code injection, which can be used to make XSS/CSRF worms such as the Samy Worm on MySpace.

False positives: The two scanner approaches just mentioned generate a massive amount of false positives for scanner users to sort through as they look for the proverbial “vulnerable needle in the haystack.” We’ve learned that most users eventually turn off the CSRF testing features; otherwise, they find themselves overwhelmed with many more results than they can possibly sort. Recently, a few scanners have tried to “tune down” the number of false positives, using some form of keyword signature matching in order to filter the false positives and raise their potential priority. This is actually one of the approaches that Sentinel uses, and has shown some merit.


How does WhiteHat Security test for CSRF?

WhiteHat’s Sentinel Service uses a combination of automation and customized tests generated by engineers in our Threat Research Center (TRC) to test for CFSR. Because CSRF is a business logic issue it is handled under the testing domain of our Sentinel Premium Edition (PE) service. One of the unique features of Sentinel PE is that our TRC engineers map out the application and teach Sentinel how to navigate logic and workflows, as well as how to create user comparison tests that usually reach across multiple users and multiple roles.

During this initial testing process we flag key areas that meet our three “actionable” CSRF criteria defined above and test them for replay-ability. As part of the ongoing scanning process, Sentinel PE also identifies new code and opens tickets that TRC engineers use to custom configure Sentinel in order to test those functions. Because most CSRF occurs in forms / POST requests it is relatively easy to capture these new functions and new features as they are released in the Web application. Of course detecting vulnerabilities in new code as it is pushed requires scanning the application on an ongoing basis.

WhiteHat also reviews every application covered by Sentinel PE service on a yearly cycle to determine whether new design patterns or coding practices have been introduced that Sentinel might otherwise overlook. For example, a new type of Web-remoting library could expose an application to CSRF without Sentinel automatically detecting it. Therefore, our standard practice is to customize and configure Sentinel for all sites we assess whenever a new design pattern or programming practice is identified.

On to Sentinel automation – specifically: automating the detection of Weak Design Patterns. During the past four years we’ve learned a lot about CSRF while testing thousands of Web applications. One of the discoveries is that some CSRFs occur in common, weak design-patterns that can often be described with a high degree of accuracy. For these cases we’ve built an automated battery of “Known Bad CSRF conditions” that Sentinel searches for. As an example, let’s consider the obvious password-reset design:

If Sentinel discovers a password-reset function that has only two input fields that both accept the same input and can be replayed, there is an extremely high likelihood that the function is CSRFable with clear security implications. Likewise, this same pattern will flag the section in a new-user account registration workflow, which is private to the user-session and located where the user first creates a password. In some cases the initial password-creation function can be re-invoked via CSRF, and then used to reset the user’s existing password after the account is created.

There are several other examples, similar to the one just described above, where describing the replay criteria is fairly straightforward once you know the name of the form or function involved in the decision / transaction.


Why does WhiteHat Security consider CSRF unresolved if there are Cross-Site Scripting (XSS) or HTTP Response Splitting (HTTP/RS) vulnerabilities present in the website?

Most anti-CSRF controls involve embedding a Dynamic Authorization Token (DAT), a token that is a one-time-use, mathematically unique nounce, into each request. Presumably, users who have not legitimately requested a page would not have the DAT required to successfully submit a CSRFable form on that page. However, if any part of the Web application is vulnerable to XSS or HTTP/RS, then an attacker can bypass the CSRF protection. For the sake of specificity, let’s call an HTTP/RS vulnerability in a resource that facilitates XSS: “XSS++”.

Specifically, the attacker will first force the victim to make a CSRF request to the XSS/++ vulnerable website, injecting the attacker’s XSS/++ attack code into the application. That XSS/++ attack will then execute in the victim’s browser, making a CSRF request to the protected resource, and will then parse the DAT required to make the protected request from the response. Finally, the attack will resend the malicious CSRF request, including the DAT that is intended to protect it. In effect, XSS/++ neuters the effectiveness of token-based CSRF compensating controls.

Because the attacker can force a legitimate user to CSRF an XSS/++ attack anywhere in a Web application, it is essential to remember that all XSS/++ are equally vulnerable to the attacker in this scenario. If the victim is logged in, it does not matter if the XSS/++ vulnerability requires authentication. And it does not matter if the XSS/++ is persistent or reflected. What does matter is to know this: All XSS/++ can be attacked equally. While persistent XSS can certainly have a larger impact over time, in regards to this specific attack scenario, all XSS attack vectors are equal.



Let’s wrap up this section with a concrete, real-world example of how a seemingly “benign” CSRF can be combined with other vulnerabilities, including XSS, to completely compromise a system. Here are the parameters: A website has no obvious CSRF vulnerabilities, but it is vulnerable to XSS, and has a Local-File Include vulnerability that potentially could allow arbitrary server-side code execution. The vulnerable application also includes a “file-upload” feature, but because you cannot CSRF the file-upload cross-domain, most scanners will ignore this particular CSRF. However, the attacker can combine CSRF + XSS + the Local File Include vulnerabilities to completely compromise the website, the Web server, and the operating system − remotely − in this scenario.

Here’s how it’s done: A user of the vulnerable website visits another website that the attacker has already hacked. The hacked website forces the user’s browser to make a CSRF attack that injects an XSS attack payload into the vulnerable website. The XSS attack fetches the attacker’s malicious PHP file, uploads it, and then exploits the Local File Include design flaw to execute the malicious PHP file on the server, taking complete control of the system − a system that appeared free from CSRF attack. All of this malicious activity occurs without the attacker making a single click, and the victim is completely unaware that anything has happened. In this manner, a seemingly innocent CSRF can be combined with other potential and known vulnerabilities to produce disastrous results.

Given these facts, if you have CSRF vulnerabilities that present real risks, it is tactically imperative to fix all of your XSS and HTTP/RS vulnerabilities while simultaneously building your CSRF protections. It is equally important to have both an ongoing website risk measurement and testing program that can identify new XSS and HTTP/RS that appear in new code as it is released, as well as a process in place to remediate the new vulnerabilities quickly. Otherwise – your CSRF vulnerabilities will always be exploitable – and your Window of Exposure to CSRF in your Web applications will be open “All Year Long.”

There are other ways to improve both software designs and development processes in the SDLC in order to reduce XSS, XSS++, and in the CSRF in new code you write. However, that subject in itself is vast and requires a longer discussion.

In summary, for the purpose of measuring and managing risk to your organization from CSRF in applications that: (1) you own; (2) you control; (3) you don’t own; (4) and/or that you can’t control, you must have − at a minimum − an ongoing tactical Web security measurement and response program for CSRF, XSS, and XSS++.

Comments or questions? Disagreements? Fire way, below: