一尘不染

CryptographicException:填充无效,无法删除,并且验证视图状态MAC失败

c#

监视我的全局异常日志,无论我做什么都似乎无法消除此错误,我以为我终于摆脱了它,但又回来了。您可以在类似的帖子中看到错误的痕迹。

有关环境的注意事项:

IIS 6.0,.NET 3.5 SP1 单服务器 ASP.NET应用程序

已经采取的步骤:

  <system.web>
    <machineKey validationKey="big encryption key"
      decryptionKey="big decryption key"
      validation="SHA1" decryption="AES" />

在我所有页面的页面库中

  protected override void OnInit(EventArgs e)
  {
    const string viewStateKey = "big key value";

    Page.ViewStateUserKey = viewStateKey;
  }

同样在页面的源中,我可以看到所有ASP.NET生成的隐藏字段都正确地位于页面顶部。


阅读 370

收藏
2020-05-19

共1个答案

一尘不染

首先让我们从事实出发, 这种视图状态错误发生在PostBack上

我还必须说 ,我已经做了每个人建议做的所有事情 来避免这个问题。而且我只有一台机器,但是有两个运行相同页面的池。

因此, 有人采取行动 ,以人为妻,通过“单击”您的页面以使其他搜索机陷入困境,或者某些黑客试图检查系统中的问题…

我遇到了类似的问题(罕见但又存在),最后我发现人们试图对我的页面进行黑客测试。(来自我拥有的IP和Dos攻击的IP)

我修改 了函数 LoadPageStateFromPersistenceMedium()
来转换视图状态,并通过记录确切的输入内容和IP地址来查看…然后我开始监视这些结果,并查看视图状态是否已手动更改-或完全为空。

发生错误时,我只是将他重定向到同一页面…

这是我做的…

public abstract class BasePage : System.Web.UI.Page
{
    protected override object LoadPageStateFromPersistenceMedium()
    {
        try
        {
            .. return the base, or make here your decompress, or what ever...
            return base.LoadPageStateFromPersistenceMedium();            
        }
        catch (Exception x)
        {
            string vsString = Request.Form[__VIEWSTATE];
            string cThePage = Request.RawUrl;

            ...log the x.ToString() error...
            ...log the vsString...
            ...log the ip coming from...
            ...log the cThePage...

        // check by your self for local errors
            Debug.Fail("Fail to load view state ! Reason:" + x.ToString());
        }

        // if reach here, then have fail, so I reload the page - maybe here you
        // can place somthing like ?rnd=RandomNumber&ErrorId=1 and show a message
        Responce.Redirect(Request.RawUrl, true);

        // the return is not used after the redirect
        return string.Empty;
    }    
}

第二个原因

现在,还有另外一个原因可以导致这种情况发生,原因是在加载__EVENTVALIDATION之前,您在页面上单击了某个按钮。

此eventValidation放置在最后一个按钮上-即使找到了asp.net,如果您在页面上的许多位置或按钮附近有一些按钮,则此操作将转到页面的末尾。

因此,即使您在页面顶部看到viewstate,验证在哪里?也许这从未加载过的页面损坏了吗?用户单击页面的速度太快了吗?

<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" ... >

为了避免此类问题,我制作了一个简单的JavaScript,除非已加载此输入,否则我不要让它按下按钮!

还有一点评论,__
EVENTVALIDATION并不总是呈现!因此,如果您提出一般的解决方案,那么不搜索此字段可能更安全,而是使用JavaScript技巧仅检查整个页面是否已加载,或者您认为其他内容。

这是我使用jQuery的最终解决方案:(请注意,如果eventvalidation存在,我将检查PageLoad!)。我已将此放置在我的MasterPages上。

<script language="javascript" type="text/javascript">
    function AllowFormToRun()
    {
        var MyEventValidation = $("#__EVENTVALIDATION");

        if(MyEventValidation.length == 0 || MyEventValidation.val() == ""){
            alert("Please wait for the page to fully loaded.");
            return false;
        }

        return true; 
    }       
</script>

protected void Page_Load(object sender, EventArgs e)
{
    // I do not know if Page can be null - just in case I place it.
    if (Page != null && Page.EnableEventValidation)
    {
        Form.Attributes["onsubmit"] = "return AllowFormToRun();";
    }
}

您可以通过在页面按钮附近放置延迟来进行测试。

<% System.Threading.Thread.Sleep(5000); %>

更新资料

今天,我再次在日志中看到了针对WebResource的消息,我发现是一个机器人在获取页面 并使链接上的所有字符都变小写
,包括参数,因此这是没有获得正确的编码字符串的又一个原因,并引发类似“ 填充”之 类的消息 ,因此无法将其删除。

希望这对您有所帮助。

2020-05-19