防止死亡的黄色屏幕

时间:2012-07-04 12:46:39

标签: asp.net postback ysod

我遇到了asp.net请求验证问题。我有一个带搜索字段和按钮的基本页面。如果用户在搜索字段中输入了一些非法字符并单击按钮,那么我当然可以在JS中验证他的输入并且一切正常。但是我也有很多LinkBut​​tons与回复的搜索功能无关,当它发生时我得到了YSOD。 我知道您可以通过在页面指令或web.config中添加ValidateRequest =“false”来关闭此功能,但是我想知道是否有比完全禁用请求验证更好更优雅的解决方案。 感谢。

3 个答案:

答案 0 :(得分:1)

您可以使用反XSS库来避免跨脚本攻击。检查此链接AntiXSS asp.net

你可以转过死亡黄屏。通过将CustomError模式更改为Remoteonly。这样远程用户就不会看到YSOD了。只有本地服务器才能看到YSOD

在web.config中

添加这样的行。

<configuration>
  <system.web>
    <customErrors defaultRedirect="yourErrorPage.html"
                  mode="RemoteOnly">

    </customErrors>
  </system.web>
</configuration>

答案 1 :(得分:0)

听起来像你需要将验证组放在你的表单元素上(可能是我误解了这个问题)。

(如果您发布了一些代码,这会更容易)

<asp:Panel runat="server" DefaultButton="btnSearch">
    <asp:TextBox runat="server" ID="txtSearch" />
    <asp:RequiredFieldValidator runat="server" ControlToValidate="txtSearch" ValidationGroup="vgSearch" ErrorMessage="Search is required!" />
    <asp:Button runat="server" ID="btnSearch" ValidationGroup="vgSearch" Text="Search" />
</asp:Panel>

<asp:LinkButton runat="server" ID="btnLogin" Text="Login" ValidationGroup="vgLogin" />
<asp:LinkButton runat="server" ID="btnCakes" Text="Cakes!" ValidationGroup="vgCakes" />

无论如何,我们的想法是你的搜索表单和相关的验证器有一个验证组,而你的其他按钮有其他验证组,那么点击另一个按钮时验证器就不会激活。

我真的不确定你是否需要针对个别链接按钮的验证组,我不认为你这样做,但我会把它们放在那里以证明我的观点。

如果我完全错过了这艘船,请告诉我:)。

编辑:

我应该提一下,我把上面的代码放在一起,不能保证它的格式正确等等。

答案 2 :(得分:0)

奇怪的是,在我试图回答这个问题的第二天,一位同事请我帮忙解决同样的问题,所以这就是我到目前为止所做的......

(请记住,虽然我已经在.Net中开发了很多年,但我从来没有必要深入研究页面生命周期,ViewState或任何保持更好的可怕的复杂位开发晚上)

最初,我认为在JavaScript中覆盖PostBack事件将允许我编辑表单帖子并删除有问题的字符,所以我尝试了一个简单的警报,但潜在危险的Request.Form 仍然出现,所以无论是什么导致它发生在PostBack事件被解雇之前。

所以,在研究了page life cycle之后,重写了我能做的每一个方法并进行了大量的调试,我发现错误是在DeterminePostBackMode方法中抛出的。

现在,根据我的理解,此方法查看表单post并将其转换为NameValueCollection,因此我构建了自己的NameValueCollection,删除了“&lt;”字符(我只用该字符开始测试)。

Protected Overrides Function DeterminePostBackMode() As System.Collections.Specialized.NameValueCollection
        Dim stream As New System.IO.StreamReader(Request.InputStream)
        Dim nvCollection As New System.Collections.Specialized.NameValueCollection()
        Dim _split() As String = stream.ReadToEnd().Split("&")
        If _split.Length > 1 Then
            For i As Integer = 0 To _split.Length - 1
                Dim kv() As String = _split(i).Split("=")
                Dim _key As String = HttpUtility.UrlDecode(kv(0))
                Dim _value As String = HttpUtility.UrlDecode(kv(1))
                If _value.Contains("<") Then _value = ""
                nvCollection.Add(_key, _value)
            Next
        End If

        'For Each s As String In nvCollection
        '    Response.Write(String.Format("<p>{0}={1}</p>", s, nvCollection(s)))
        'Next

        Return nvCollection
    End Function

这种方法非常出色,正在删除违规的值并返回NameValueCollection而不会导致错误......

除了我仍然看到错误消息。

目前,我已将其跟踪到PreInit页面事件,我正试图找到解决方法,我会在我取得进展时更新它。

更新:

我现在很确定问题不在于存储在ViewState中的值。在阅读了关于ViewState的this优秀文章后,我尝试以声明方式将TextBox的值设置为"<script",这意味着它不应存储在ViewState中,这意味着错误不是由处理在ViewState上进行。

我想。