<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://keepitlocked.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>KeepItLocked.net : CSRF, .NET ESAPI</title><link>http://keepitlocked.net/archive/tags/CSRF/.NET+ESAPI/default.aspx</link><description>Tags: CSRF, .NET ESAPI</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP2 (Build: 20611.960)</generator><item><title>Preventing CSRF with CsrfGuard</title><link>http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx</link><pubDate>Fri, 17 Oct 2008 22:00:00 GMT</pubDate><guid isPermaLink="false">a3f75fb5-0505-4d35-9795-aaa2ed659a71:38</guid><dc:creator>Alex</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://keepitlocked.net/rsscomments.aspx?PostID=38</wfw:commentRss><comments>http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx#comments</comments><description>&lt;p&gt;Edit: I realized I didn't mention the multitude of other ways to discourage CSRF including re-authentication, CAPTCHA, referrer checking, etc. This article deals only with the "secret token" approach to stopping CSRF.&lt;br&gt;&lt;/p&gt;&lt;p&gt;CSRF (&lt;a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery" mce_href="http://en.wikipedia.org/wiki/Cross-site_request_forgery"&gt;Cross-Site Request Forgery&lt;/a&gt;) attacks occur when an attacker forces a victim to perform an action unintentionally - "forging" a request from the victim, usually by using &amp;lt;img&amp;gt; tags (GET) or self-submitting forms (POST) in an attacker-controlled page the victim views.
&lt;/p&gt;&lt;p&gt;CSRF attacks work because the browser likes to "auto-authenticate" to sites. Session IDs in cookies, HTTP, and NTLM authentication tokens are all automatically sent by the browser when it makes a request to a site. Thus, when the victim makes a request to site unintentionally, they do so with their full privileges.
&lt;/p&gt;&lt;p&gt;A simple solution is to include an additional, unguessable token as a request argument. The application verifies this CSRF token against a server-side copy (or a cookie). If there's a mismatch, then a CSRF exception should be raised. This would prevent the attacker from forging the request because they can't set up a valid form without this secret value.
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;&amp;lt;form action="whatever.page" method="POST"&amp;gt;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;…
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;&amp;lt;input type="hidden" name="CSRFToken" value="SomeSecretValue" /&amp;gt;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;&amp;lt;input type="Submit" value="Click Me"/&amp;gt;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;&amp;lt;/form&amp;gt;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This type of solution is suggested by some &lt;a href="http://www.gnucitizen.org/blog/preventing-csrf/" mce_href="http://www.gnucitizen.org/blog/preventing-csrf/"&gt;reputable&lt;/a&gt;
		&lt;a href="http://freedom-to-tinker.com/sites/default/files/csrf.pdf" mce_href="http://freedom-to-tinker.com/sites/default/files/csrf.pdf"&gt;sources&lt;/a&gt; in &lt;a href="http://shiflett.org/articles/cross-site-request-forgeries" mce_href="http://shiflett.org/articles/cross-site-request-forgeries"&gt;application&lt;/a&gt;
		&lt;a href="http://www.isecpartners.com/files/XSRF_Paper_0.pdf" mce_href="http://www.isecpartners.com/files/XSRF_Paper_0.pdf"&gt;security&lt;/a&gt;. In some cases, the CSRF token is the session ID.&lt;span style="font-family: Courier New;"&gt;
		&lt;/span&gt;&lt;/p&gt;&lt;p&gt;There are problems with this solution. The salient issue is the difference between GET and POST. According to &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html" mce_href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html"&gt;RFC 2616&lt;/a&gt;, GET requests should be idempotent, meaning that they should not cause observable state-change on the server-side. If there was an RFC for CSRF, it would prohibit CSRF attacks against GET targets for this reason – there would is no reason to forge idempotent request. However, this is simply not the way GET is used in the real-world – it is used directly (the application has non-idempotent hyperlinks) or indirectly (the application accepts GET arguments just like they were POST arguments).
&lt;/p&gt;&lt;p&gt;So, GET requests need to be protected, too. Easy enough:
&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.keepitlocked.net/whatever.page?CSRFToken=SomeSecretValue" mce_href="http://www.keepitlocked.net/whatever.page?CSRFToken=SomeSecretValue"&gt;&lt;span style="font-family: Courier New;"&gt;http://www.keepitlocked.net/whatever.page?CSRFToken=SomeSecretValue&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Courier New;"&gt;
		&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This works, but it's inelegant. It ruins bookmarking. Furthermore, if the CSRF token is the session ID, then placing it into a GET argument will cause it to be stored in server and proxy logs and browser history, which makes the session identifier secret more difficult to keep.
&lt;/p&gt;&lt;p&gt;So, a full-featured CSRF solution is more difficult than it seems.
&lt;/p&gt;&lt;p&gt;The &lt;a href="http://www.owasp.org/index.php/CSRF_Guard" mce_href="http://www.owasp.org/index.php/CSRF_Guard"&gt;CsrfGuard&lt;/a&gt; project is a fairly compelling solution – it overwrites all forms (POST) with an additional CSRF token argument, and it also overwrites links (GET). But, there are cases where links do not get a token:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The link doesn't have any arguments (in which case it's likely idempotent).
&lt;/li&gt;&lt;li&gt;The link is to a .gif or other whitelisted extension.
&lt;/li&gt;&lt;li&gt;The link is in a configurable whitelist of URLs (for pages which are known to be idempotent).
&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I like this approach because it offers the maximum amount of protection, not simply relying on developers to follow the standard and penalizing them with vulnerabilities if they don't.
&lt;/p&gt;&lt;p&gt;That's why I'm integrating the &lt;a href="http://www.owasp.org/index.php/.Net_CSRF_Guard" mce_href="http://www.owasp.org/index.php/.Net_CSRF_Guard"&gt;.NET CsrfGuard&lt;/a&gt; project into OWASP &lt;a href="https://www.owasp.org/index.php/.NET_ESAPI" mce_href="https://www.owasp.org/index.php/.NET_ESAPI"&gt;.NET ESAPI&lt;/a&gt;. It will require some tweaking, but it's the most comprehensive functionality preventing CSRF I've seen.
&lt;/p&gt;&lt;p&gt;One tweak is that the CSRF token should not be the session ID, because it increases the risk of exposure. Instead, I'll use the hash(Session ID + Salt).  This is all easily configurable with CsrfGuard.
&lt;/p&gt;&lt;p&gt;Oh yeah, what about &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.page.viewstateuserkey.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.page.viewstateuserkey.aspx"&gt;ViewStateUserKey&lt;/a&gt;? Well, it's still there, with the weaknesses &lt;a href="http://keepitlocked.net/archive/2008/05/29/viewstateuserkey-doesn-t-prevent-cross-site-request-forgery.aspx" mce_href="http://keepitlocked.net/archive/2008/05/29/viewstateuserkey-doesn-t-prevent-cross-site-request-forgery.aspx"&gt;I've written about before&lt;/a&gt;. To me, it's like &lt;a href="http://keepitlocked.net/archive/2007/10/30/asp-net-validaterequest-and-the-html-attribute-based-cross-site-scripting.aspx" mce_href="http://keepitlocked.net/archive/2007/10/30/asp-net-validaterequest-and-the-html-attribute-based-cross-site-scripting.aspx"&gt;ValidateRequest&lt;/a&gt; – use it, but don't rely on it.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx&amp;amp;;subject=Preventing+CSRF+with+CsrfGuard" target="_blank" title = "Post http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx&amp;amp;;title=Preventing+CSRF+with+CsrfGuard" target="_blank" title = "Post http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx&amp;amp;title=Preventing+CSRF+with+CsrfGuard" target="_blank" title = "Post http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx&amp;amp;;title=Preventing+CSRF+with+CsrfGuard" target="_blank" title = "Post http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx&amp;amp;;title=Preventing+CSRF+with+CsrfGuard&amp;amp;;top=1" target="_blank" title = "Post http://keepitlocked.net/archive/2008/10/17/preventing-csrf-the-right-way.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://keepitlocked.net/aggbug.aspx?PostID=38" width="1" height="1"&gt;</description><category domain="http://keepitlocked.net/archive/tags/Software+Security/default.aspx">Software Security</category><category domain="http://keepitlocked.net/archive/tags/CSRF/default.aspx">CSRF</category><category domain="http://keepitlocked.net/archive/tags/.NET+ESAPI/default.aspx">.NET ESAPI</category><category domain="http://keepitlocked.net/archive/tags/OWASP/default.aspx">OWASP</category></item></channel></rss>