Preventing the yellow screen of death

6.4k Views Asked by At

I'm having a problem with asp.net request validation. I have a basic page with a search field and a button. If the user inputs some illegal characters in the search field and clicks the button then of course I can validate his input in JS and everything's OK. However I have also a lot of LinkButtons not associated with the search functionality that do postbacks and when it happens I get the YSOD. I know you can turn this feature off by adding ValidateRequest="false" in page directives or web.config, however I'd like to know if there is better and more elegant solution than simply disabling request validation completely. Thanks.

3

There are 3 best solutions below

5
On

Sounds to me like you need to put validation groups against your form elements (could be I'm misunderstanding the question).

(This would be easier if you'd have posted some code)

<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" />

Anyway, the idea is that your search form and associated validators have one validation group, and your other buttons have other validation groups, then the validator won't fire when you click another button.

I'm not actually sure if you NEED the validation groups against individual link buttons, I don't think you do, but I'm putting 'em in there to demonstrate my point.

If I've completely missed the boat, let me know :)

EDIT:

I should mention that I've just thrown the above code together, can't guarantee it's all formatted correctly, etc, etc.

0
On

Oddly enough, the day after I attempted to answer this, a co-worked asked me to help with the same problem, so here's what I'm up to so far...

(Bare in mind that while I've been developing in .Net for a number of years, I've never had need to delve that deeply into the page life cycle, ViewState or any of the hideously complicated bits that keep better dev's up at night)

Initially, I thought that overriding the PostBack event in JavaScript would allow me to edit the form post and remove the offending characters, so I tried it with a simple alert, but the potentially dangerous Request.Form was still appearing, so whatever's causing it is happening before the PostBack event is being fired.

So, after investigating the page life cycle, overriding every method I could and doing a whole lot of debugging, I found that the error is being throw in the DeterminePostBackMode method.

Now, by my understanding, this method looks at the form post and converts it to a NameValueCollection, so I built my own NameValueCollection, stripping out the "<" character (I only tested with that character to start with).

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

And that worked brilliantly, the offending value was being stripped out and the NameValueCollection was being returned without causing an error...

Except I was still seeing the error message.

At the moment, I've tracked it to the PreInit page event, and I'm trying to figure a way around it, I'll update this as I make progress.

UPDATE:

I'm now fairly sure that the issue ISN'T with the values being stored in the ViewState. After reading this excellent article on ViewState, I tried setting the value of a TextBox to "<script" declaratively, which means it shouldn't be stored in the ViewState, which means that the error isn't caused by processing being carried out on the ViewState.

I think.

6
On

you can use anti XSS Library to avoid cross scripting attack. check for this link AntiXSS asp.net .

and you can turn of the Yellowscreen of Death. by changing the CustomError mode to Remoteonly. so that remote user wont see the YSOD. only local server will see the YSOD

in web.config add line like this.

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

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