comments (not for humans)
There are several ways to implement XSRF protection. In this implementation I'll use a combination of Viewstate and session to check the validity of a request.

The problem
A hacker can fool a user's browser into doing a request against a page using javascript. This request was not intended and is thus a Cross site request forgery (XSRF/CSRF). Read more about XSRF here.

The protection
To protect against this attack, the request must contain a value or id specific to the user, and this id should be impossible to guess by the attacker. The id must be submitted with each post, and checked when receiving the post.

This code is based upon subclassing the System.Web.UI.Page class. We override the OnPreLoad-function (cannot use OnPreInit as the viewstate is not loaded).

This is the code for the Page subclass called basePage.

public class BasePage : Page
{
private bool _isXsrf;
private const string _XsrfName = "_XSID";
public bool IsXsrf
{
get { return _isXsrf; }
}


protected override void OnPreLoad(EventArgs e)
{
base.OnPreLoad(e);
string sessionXsrfId = Session[_XsrfName] as string;
if (IsPostBack)
{
string vwId = ViewState[_XsrfName] as string;
_isXsrf = true;
if (!string.IsNullOrEmpty(vwId) && vwId.Equals(sessionXsrfId))
{
_isXsrf = false;
}
}
else
{
if (string.IsNullOrEmpty(sessionXsrfId))
{
sessionXsrfId = GenerateCode();
Session.Add(_XsrfName, sessionXsrfId);
ViewState.Add(_XsrfName, sessionXsrfId);
}
}
}

private static string GenerateCode()
{
RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
byte[] randBytes = new byte[32];
random.GetNonZeroBytes(randBytes);
return Convert.ToBase64String(randBytes);
}
}


Each page you create must now inherit BasePage instead of System.Web.UI:Page:
public partial class _Default : BasePage
In the Page_Load method of your pages you can now do:
if (IsXsrf) {
//throw security exception or similar
}

Advantages
Leverages existing functionality and requires only a couple of lines of code for each page.

Drawbacks
Always returns true on XSRF if user has disabled cookies, as the user will not be able to keep the session.
Dinis Cruz

HttpModules

Hi

You could also do this using HttpModules which would not required any code changes (only 1 line change on web.config)

Dinis Cruz
OWASP .NET Project
Erlend

Re:HttpModules

You can? Cool. Can you explain?
Erik K.

How about pages in frames?

Hi,

I can't see this work when you have an application consisting of multiple frames since it stores the information in the session and will overwrite it for each page in a frame
Erlend

Re: How about pages in frames?

There are a couple of options. You could either generate one key and reuse it for the entire session. Or you could prefix the sessionkey with the name of the page.
OWASP CSRF guard might be an option: http://www.owasp.org/index.php/Category:OWASP_CSRFGuard_Project
Comments closed for this post