May 29, 2007 - 22:13 UTC - Tags: XSRF security ASP.NET
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 problemA 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 protectionTo 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
}
AdvantagesLeverages existing functionality and requires only a couple of lines of code for each page.
DrawbacksAlways returns true on XSRF if user has disabled cookies, as the user will not be able to keep the session.