Event Validation Errors and Network Congestion in ASP.NET

Friday, April 13, 2007

Joseph Rattz emailed me about posts I wrote last year covering ASP.NET event validation (see ASP.NET Event Validation and "Invalid Callback Or Postback Argument" Part I and Part II). In the posts I describe one scenario where an event validation exception can appear, and describe how to prevent the exception. In the scenario, client side script dynamically adds values to a list (select) control. When the user POSTs the form to the server, ASP.NET sees a new value and concludes something is wrong. The list comes back to the server with a value that wasn't present when the list left the server. ASP.NET tracks the legal values by serializing them into a hidden input control with an ID of __EVENTVALIDATION. This event validation feature helps to prevent all sorts of form spoofing attacks.

Joe's scenario was odd, not only because the invalid postback argument exception appeared sporadically, but because the source of the exception was a TextBox control!

ArgumentException: Invalid postback or callback argument.  ...
  System.Web.UI.ClientScriptManager.ValidateEvent(..) ...
  System.Web.UI.Control.ValidateEvent(..) ...
  System.Web.UI.WebControls.TextBox.LoadPostData(..) ...

 

What could ASP.NET possibly validate about a TextBox? A server can expect specific values from a DropDownList, but a plain TextBox allows free form text entry by the user. The answer (via Reflector), is that the TextBox control only validates that its UniqueID is present in the legal arguments described by the __EVENTVALIDATION data. Even after knowing this information, it's hard to see what could go possibly wrong with a TextBox.

Joe's theory, which I believe to be correct, is that the user might create a postback before their browser even receives the __EVENTVALIDATION form input. This could happen, for example, over a poor connection. The resulting POST won't contain the __EVENTVALIDATION input, and thus ASP.NET cannot validate the postback arguments. The klaxons wail. Glass breaks. The runtime throws an exception.

One way to validate this theory is to simulate network congestion with the following control. We flush out the output stream, sleep, and then continue rendering.

using System;
using System.Web.UI;
using System.Threading;

namespace OTC
{
    
public class FlushAndSleep : Control
    {
        
protected override void Render(HtmlTextWriter writer)
        {
            writer.Write (
"Begin Render<br>");

            
base.Render (writer);

            Page.Response.Flush();

            
Thread.Sleep(2000);
            writer.Write(
"End Render<br>");
        }
    }
}

 

Stick the control into the following page:

<%@ Page Language="C#" %>
<%
@ Register TagPrefix="otc" Assembly="App_Code" Namespace="OTC" %>

<form id="form1" runat="server">
    <div>
        <asp:textbox runat="server" id="TextBox1" />
        <asp:button runat="server" id="Button1" text="Submit" />
        <br />        
        
<otc:FlushAndSleep runat="server" ID="FlushAndSleep" />
    </div>
</
form>

 

Run the page and click the button as soon as it appears in the browser. Voila! Instant "invalid callback or postback argument" exception! If you ever see the exception occur sporadically, this might be the reason.


Comments
Skup Monday, April 16, 2007
I also think that this is the reason, we spoted it on a web site we're working on.
The poor solution we had to adopt was sadly to disable the event validation.
Any idea of something better ?
scott Tuesday, April 17, 2007
Skup:

I don't know of an easy answer. It might be possible to start with all postback controls disabled and enable them in a window.onload event, or something along those lines - but it adds a lot of complexity to the page..
Matt Thursday, April 19, 2007
Any idea why the event validation field renders so late in the page? Looks like its called from Page.EndFormRender, whereas the viewstate and other hidden fields are rendered from the BeginFormRender method.

I'm sure Microsoft had some reason for doing it this way that hasn't occurred to me. It just seems like rendering it earlier would decrease the likelihood of this error.
scott Thursday, April 19, 2007
I think they are waiting until after all the server-side controls have rendered - if effect giving them up until the last minute to decide what thier legal postback values can contain.
gravatar prity Thursday, April 29, 2010
Validation Event
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!