【发布时间】:2017-07-25 11:45:23
【问题描述】:
我正在开发一个 Asp.net 网络表单应用程序。我正在尝试在应用程序中实现防伪令牌功能。
我有一个测试用例,其中使用 XHR 从不同文件(CSRF 问题)中的脚本调用应用程序。在我更改脚本中的 ViewState 值之前,我实施的解决方案可以正常工作。
以下是整个场景。
请看下面脚本中的 "\r\n" blah blah blah... ;。
外部脚本(CSRF 攻击脚本):
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]));
我在应用中的解决方案:
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
代码块说明:
当我的一个页面加载时,我在ViewState 以及会话中设置加密的 GUID。之后,当用户进行任何服务器调用时,它只会比较ViewState 和会话的值。如果ViewState的解密值与session的解密值不匹配,则表明该方法是从应用程序外部调用的。
以上解决方案完美运行。
但是当我改变 ViewState 的值如下:
"**Test**\r\n" blah blah blah... ;
我的代码无法验证它,因为它进入了If Not Page.IsPostBack Then 部分并设置了空白ViewState 值。只需在脚本中添加“测试”即可。任何有 Asp.net 经验的人都可能知道这里的问题。请解释这个案例的确切问题和解决方案...
问候
【问题讨论】:
-
如果启用 ViewStateMAC,则无法修改视图状态
-
我没有任何启用 ViewStateMAC 的页面。将上述视为许多 aspx 页面的通用解决方案。所以我现在不能手动更改所有页面。
标签: c# asp.net vb.net webforms antiforgerytoken