<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Playing on the frontier &#187; csrf</title>
	<atom:link href="http://siphon9.net/loune/tag/csrf/feed/" rel="self" type="application/rss+xml" />
	<link>http://siphon9.net/loune</link>
	<description></description>
	<lastBuildDate>Thu, 15 Jul 2010 12:58:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Verifying Anti-Forgery Token for Form POST only</title>
		<link>http://siphon9.net/loune/2010/02/verifying-anti-forgery-token-for-form-post-only/</link>
		<comments>http://siphon9.net/loune/2010/02/verifying-anti-forgery-token-for-form-post-only/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 01:03:37 +0000</pubDate>
		<dc:creator>Loune</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[aspnetmvc]]></category>
		<category><![CDATA[csrf]]></category>

		<guid isPermaLink="false">http://siphon9.net/loune/?p=151</guid>
		<description><![CDATA[As many of you know, the ASP.NET MVC Anti-Forgery token helps thwart Cross Site Request Forgery attacks. Any site that uses authenticated sessions (99% of web apps) should use similar mechanisms so these attacks cannot occur. Very often, I would write GET and POST actions in the same method. This allows fall through to that [...]]]></description>
			<content:encoded><![CDATA[<p>As many of you know, the ASP.NET MVC Anti-Forgery token helps thwart <a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery">Cross Site Request Forgery</a> attacks. Any site that uses authenticated sessions (99% of web apps) should use similar mechanisms so these attacks cannot occur.</p>
<p>Very often, I would write GET and POST actions in the same method. This allows fall through to that same code we used for GET request if POST validation fails, ensuring consistency.</p>
<pre class="brush: csharp;">
public ActionResult EditPerson(Person person)
{
	if (Request.HttpMethod == &quot;POST&quot; &amp;&amp; ModelState.IsValid)
	{
		// do edit person...

		return RedirectToAction(&quot;Index&quot;);
	}

	// do get person

	return View(person);
}
</pre>
<p>If I use that sort of paradigm, then the [VerifyAntiForgeryToken] attribute would block both GET and POST requests when the token is not supplied. I want the token to be only verified when I POST. Since ASP.NET MVC is extensible, the normal way to go about that would be modify the behaviour of [VerifyAntiForgeryToken] by subclassing. Unfortuantely, VerifyAntiForgeryTokenAttribute is sealed which means it can&#8217;t be inherited from. Luckily, borrowing from the same trick that Http*Base classes use to combat sealed Http* classes, we can just create a new attribute that wraps the old attribute, implementing the same members and proxying the calls back to the wrapped base class. That&#8217;s exactly what I did and it works quite well. The result is [ValidateAntiForgeryTokenOnPost] which will only verify the form anti-forgery token on a POST request:</p>
<pre class="brush: csharp;">
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ValidateAntiForgeryTokenOnPostAttribute : FilterAttribute, IAuthorizationFilter
{
	private ValidateAntiForgeryTokenAttribute _wrapped;
	public ValidateAntiForgeryTokenOnPostAttribute()
	{
		_wrapped = new ValidateAntiForgeryTokenAttribute();
	}

	public string Salt { get { return _wrapped.Salt; } set { _wrapped.Salt = value; } }

	public void OnAuthorization(AuthorizationContext filterContext)
	{
		if (filterContext.HttpContext.Request.HttpMethod == &quot;POST&quot;)
		{
			_wrapped.OnAuthorization(filterContext);
		}
	}
}
</pre>
<p>This will teach those sealed classes!</p>
]]></content:encoded>
			<wfw:commentRss>http://siphon9.net/loune/2010/02/verifying-anti-forgery-token-for-form-post-only/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
