【问题标题】:Failing validation of Anti Forgery Token in Asp.net webform applicationAsp.net webform 应用程序中的防伪令牌验证失败
【发布时间】: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


【解决方案1】:

所以我找到了解决方案。

  1. 我可以在这里检查导致回发的控件。

  2. 1234563
  3. 基于控件,我可以区分实际的回发事件并相应地做进一步的代码。

请让我知道此解决方案是否有效,否则将来可能会导致问题。 从this 帖子中找到解决方案。

解决方案:

Protected Overrides Sub OnLoad(ByVal e As EventArgs)
    Try
        Dim ControlPostBack As Control = GetControlThatCausedPostBack(Me)
        If Not Page.IsPostBack Then
            If ControlPostBack Is Nothing Then
                ViewState("AntiforgeryToken") = ""
            End If
        End If

        Dim OutString As String = Convert.ToString(ViewState("AntiforgeryToken"))
        AntiforgeryChecker.Check(Me.Page, OutString, ControlPostBack)
        ViewState("AntiforgeryToken") = OutString

    Catch ex As Exception
        Handled()
    End Try
End Sub


Private Function GetControlThatCausedPostBack(page As Page) As Control
    Dim ctrl As Control = Nothing
    Dim ctrlName As String = page.Request.Params.[Get]("__EVENTTARGET")
    If Not [String].IsNullOrEmpty(ctrlName) Then
        ctrl = page.FindControl(ctrlName)
    End If
    Return ctrl
End Function

【讨论】:

    猜你喜欢
    • 2014-01-23
    • 1970-01-01
    • 2019-11-19
    • 2018-07-11
    • 2018-04-13
    • 2018-06-19
    • 2021-06-09
    • 2015-08-15
    • 2015-06-03
    相关资源
    最近更新 更多