I am working on an Asp.net webforms application. I am trying to implement anti forgery token functionality in the application.
I have a test case where the application is called from a script in a different file (CSRF issue) using XHR. The solution I have implemented works properly until I change a value of ViewState
in the script.
Following is the whole scenario.
Look at "\r\n" blah blah blah... ; in below script.
External script (CSRF attack script):
var xhr = new XMLHttpRequest();
xhr.open("POST", "MyAppDomain", true);
xhr.setRequestHeader("Accept", "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8");
xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.5");
xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=---------------------------12421522427704");
xhr.withCredentials = true;
var body = "-----------------------------12421522427704\r\n" +
"Content-Disposition: form-data; name=\"Element\"\r\n" +
"\r\n" +
"Search here...\r\n" +
"-----------------------------12421522427704\r\n" +
"Content-Disposition: form-data; name=\"ddlRecordPerPage_Value\"\r\n" +
"\r\n" +
"-----------------------------12421522427704\r\n" +
"Content-Disposition: form-data; name=\"__EVENTARGUMENT\"\r\n" +
"\r\n" +
"btnEditProfileSave|event|Click\r\n" +
"-----------------------------12421522427704\r\n" +
"Content-Disposition: form-data; name=\"__VIEWSTATE\"\r\n" +
"\r\n" +
"\r\n" blah blah blah... ;
var aBody = new Uint8Array(body.length);
for (var i = 0; i < aBody.length; i++)
aBody[i] = body.charCodeAt(i);
xhr.send(new Blob([aBody]));
My solution in the application:
If Not Page.IsPostBack Then
ViewState("AntiforgeryToken") = ""
Else
Dim OutString As String = If(Not String.IsNullOrEmpty(Convert.ToString(ViewState("AntiforgeryToken"))), Convert.ToString(ViewState("AntiforgeryToken")), "")
If String.IsNullOrEmpty(OutString) AndAlso OutString = "initialize" Then
Throw New Exception("Unknown request source.")
Ext.Net.X.Redirect(AppPath() & "/Login.aspx", "Invalid request scope.")
End If
AntiforgeryChecker.Check(Me.Page, OutString)
ViewState("AntiforgeryToken") = OutString
End If
Code block explanation:
When one of my page loads, I am setting encrypted GUID in the ViewState
as well as in the session. After it, when a user makes any server call, it will only compare the value of ViewState
and session. If the decrypted value of the ViewState
does not match with the decrypted value of session, indicates that the method is being called from the outside of the application.
Above solution works perfectly.
But when I change the value of ViewState as following:
"**Test**\r\n" blah blah blah... ;
My code fails to validate it because it goes to the If Not Page.IsPostBack Then
part and sets blank ViewState
value. It occurs just by adding "Test" in the script. Anyone with Asp.net experience may know the issue here. Please explain the exact issue and the solution this case...
Regards