[WEB SECURITY] Re: Suggestions for the CSRF FAQ

bugtraq at cgisecurity.net bugtraq at cgisecurity.net
Sun Jan 28 15:35:32 EST 2007

> The CSRF FAQ at http://www.cgisecurity.com/articles/csrf-faq.shtml is
> a great document, and sorely needed.  I've got some suggestions for
> two of the questions in the FAQ.

Thanks for emailing suggestions. This is a living document and all are welcome.

> > What can I do to protect myself as a user?
> The FAQ's current answer is that user's are helpless.  Is that really
> true?  If you restrict the web sites you visit you can reduce your
> exposure.  If you limit the amount of time you are logged into web
> sites you can reduce your exposure.  For example, if you are concerned
> about CSRF attacks on your bank account, limit the amount of time you
> are logged in to your bank's web site.  Log in only when you need to
> perform a task, and close the browser as soon as you are done with the
> site.  Also, don't visit other web sites or view untrusted documents
> while you are logged in to your bank's site.

You also need to consider sites not requiring you to login to use certain site functionality. Example 'email a friend',
filling out a contact form, posting to a bbs or forum. Not all sites will require you to be authed to perform these functions
which is why I say there is no generic solution. Now for sites requiring a login you could blow away the cookies sure, but it is possible
to be exploited via CSRF while still logged in via an email, aim, xss, or visiting another website in another window. I guess
I could add something along the lines of 'For sites requiring the user to be logged in to perform a specific site task, only
have one browser window open to that site only and after performing the actions you want, blow away all cookies and ensure that
you are signed out properly'. 'For sites not requiring you to be logged in to perform a site action there is nothing that you can do'.

> > What can I do to protect my own applications?
> I think the FAQ's answer to this question is basically correct, but a
> little more detail about the trade-offs involved in the different
> solutions might be helpful.  I've written up a few notes (OK, a lot of

I references IsecPartners paper on the various session/token methods since they have the tradeoffs

> notes) about how to go about adding CSRF protection to various types
> of applications.  I'd appreciate some constructive criticism on these
> approaches.  If there is consensus that these approaches are
> technically sound and make sense in the real world, perhaps they
> should be included in the FAQ.
> *** Before you start adding CSRF protection ***
> The first step in protecting your application against CSRF is to fix
> any cross-site scripting vulnerabilities.  If your application is
> vulnerable to XSS, CSRF protection is not possible.  Javascript
> malware will defeat whatever protection you put in place.

I basically said this however clearified it a bit.

" If a single XSS flaw exists, then there is no
good way (at the time of this writing) to prevent a CSRF issue from being exploited, and for this reason
you must ensure that your application and website are free from XSS issues.

> The next step is to identify which functions of your application you
> want to protect against CSRF.  Not all function needs to be protected.
>  In fact, CSRF protection can make your web application less useful
> because it prevents others from linking to portions of your site.
> Which parts of your application require CSRF protection is ultimately
> a business decision, but as a general guideline pages that cause
> changes to data should be protected against CSRF.  Pages that display

Actually this is a good point. The protection I labeled as best in the faq is to take the approach amazon
and other large sites use which require logging in to perform each important site function.  

> data without changing it probably don't require CSRF protection.  For
> example, a page that shows a stock quote probably doesn't require CSRF
> protection (wouldn't you like other sites to be able to link directly
> to that page?)  A page that triggers a stock purchase probably does
> merit CSRF protection.
> Once you've decided which functions require CSRF protection, there are
> several mechanisms for providing that protection.  Broadly speaking,
> CSRF protection mechanisms fall into two categories, those that reduce
> target surface and those that prevent cross-site linking.

I've added some text specifically outlining the decisions needing to be made
on site functionality.

> *** Reducing target surface ***
> CSRF attacks rely on using a session that a user has already
> established to trigger an action without the user's consent.  In

Again may depend on the application/site. 
I can still make a user relay spam/bbs posts without their knowledge.

> general, if a user is not logged in, that user cannot be affected by a
> CSRF attack.  You can reduce the risk of a successful CSRF attack by
> using short session activity timeouts in your application.  If a user
> has been inactive for several minutes, log them out of the
> application.  The choice of session time limits poses a trade-off
> between usability and security and is ultimately a business decision
> rather than a technical one.  If your users complain about being
> prompted to log in frequently, you may need to increase the time
> limits.

I added some text to clearify session expiration.

> Requiring POST requests can also reduce target surface, by making it
> harder for attackers to find an accomplice web site to use as a
> launching pad for the CSRF attack
> (http://www.webappsec.org/lists/websecurity/archive/2007-01/msg00158.html).

I mention in the FAQ how many applications allow POST to GET conversation and visa versa. Strictly
using POST is considered a general best practice for sensitive data to avoid being
cached in a proxy/log somewhere. To be honest with you I don't think only using POST
is necessaraly a good solution to CSRF that should be preached to the masses. Anyone else have any comments
about this?

>  Many popular web sites restrict the HTML content that users can
> create, but do allow arbitrary img tags.  Such web sites can be used
> as unwitting accomplices to a CSRF attack.  One of your users may view
> a page on such a site that contains an attacker controlled img tag.
> Their browser will then automatically send a GET request.  If your
> application accepts such GET requests as legitimate, then an attacker
> has a wide choice of potential accomplice web sites.
> It is possible to automatically send a POST request from a browser,
> but it requires a wider degree of control over the HTML page.  In
> general a user will need to view an attacker controlled web page in
> order to trigger an attack using a POST request.  This limits the
> number of potential accomplice web sites an attacker can choose from.

One could create a form on a third party site to auto POST to your site. This is mentioned in the FAQ.  

> *** Preventing cross-site linking ***
> Reducing target surface is a good idea, but should not be your only
> line of defense for CSRF protection.  Stronger CSRF protection
> requires making it impossible for other web sites to trigger an action
> on your web site.  This can be done either via the use of secret
> tokens that are included and verified with form submissions, or by
> requiring that a user confirm a request by submitting a password or
> other authentication code as the final step in a transaction.  Neither
> of these mechanisms is perfect from a security perspective.

Agreed, and both are mentioned in this document.

> The problem with asking users to reenter their password frequently is
> that it makes for a poor user interface.  People may complain.  Aside
> from the usability problems, frequent password prompts encourage
> people to type in their password without thinking, and so may increase
> your exposure to phishing attacks.  It also needs to be noted that an
> XSS vulnerability in your site could allow javascript malware to sniff
> the password as the user types it in.

This was already noted in the document. 
Either way I like that you're bringing this discussion to the lists. Perhaps someone reading this thread
has a better suggestion?

> However, secret tokens pose some security risks of their own.  An XSS
> vulnerability in your web site means that attackers can read your
> secret tokens, so you must fix your XSS vulnerabilities before
> attempting to add CSRF protection to your web site.  Aside from XSS
> bugs making your CSRF protection useless, the IE mthml vulnerability
> (http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-2111) can also
> let an attacker read your secret tokens.  The IE mhtml bug violates
> the browser same-origin security model, and so it will probably be
> fixed eventually.  (Also see
> http://sla.ckers.org/forum/read.php?4,1975#msg-2036 for an interesting
> discussion of how to prevent the mhtml bug from reading pages on your
> web site.)

Browser vulnerabilites are going to to be something that the site can't protect against at this time and is mentioned
in this document.

> Poorly configured Flash crossdomain.xml files can also make CSRF
> protection more difficult
> (http://www.hardened-php.net/library/poking_new_holes_with_flash_crossdomain_policy_files.html).
>  The flash crossdomain.xml file is a feature, not a bug, so you will
> need to deal with this problem for the forseeable future.  You can
> mitigate the risk of this feature being used against you by being
> cautious in what you include in crossdomain.xml files.

Flash (for this use case) would fall under browser/browser plugins.

> Despite the problems with using secret tokens for CSRF protection,
> this tactic is widely used.  The different mechanisms of generating
> and verifying tokens merit discussion.  Which method is best for you
> depends on your web development platform and the requirements of your
> application.
> If your platform supports sessions, then you can generate a
> cryptographically strong random number and store it in both the
> session and as a hidden form field.  When processing the form
> submission, verify that the token submitted with the form matches the
> token stored with the session.  The secret token should be changed
> periodically and should be generated independently for each user.  How
> often to change the secret token is a matter of some debate.  Changing
> the token frequently mitigates the risk of an attacker guessing the
> token or obtaining it through some other means.  However, if the token
> changes too frequently then you risk breaking your web application for
> those people that use the back button of their browser.  A user might
> hit the back button a few times, then submit a form from a cached
> page.  If the token has changed since the page was cached, your web
> application will have to reject the form submission even though no
> CSRF has occurred.

I've seen this myself on a previous customer site and the back button is not available :)

> If your platform does not support sessions and you prefer not to use
> HTTP cookies, http://developer.yahoo.com/security/ offers a solution
> under the heading "Protect Against Request Forgeries".  Include a
> user-specific cryptographic signature with your forms and verify the
> signature when processing the form submission.  The key element of
> this solution is that an attacker must be unable to predict at least
> one of the signed elements.

Hadn't heard of that before thanks for mentioning it I'll check it out. Thanks for the comments Brian.

- Robert 
http://www.cgisecurity.com/index.rss [RSS Feed]

Join us on IRC: irc.freenode.net #webappsec

The Web Security Mailing List: 

The Web Security Mailing List Archives: 
http://www.webappsec.org/rss/websecurity.rss [RSS Feed]

More information about the websecurity mailing list