ASP.NET Event Validation and “Invalid Callback Or Postback Argument” : Part I

http://odetocode.com/blogs/scott/archive/2006/03/20/asp-net-event-validation-and-invalid-callback-or-postback-argument.aspx

ASP.NET 2.0 added a feature called event validation. Event validation checks the incoming values in a POST to ensure the values are known, good values. If the runtime sees a value it doesn’t know about, it throws an exception.

Invalid postback or callback argument. Event validation is enabled using <pages enableeventvalidation="true" /> in configuration or <%@ page enableeventvalidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

The error message is a bit wierd and could use some editing, but if someone is trying to attack the application by spoofing a postback, the event validation exception is agood thing. Event validation can help prevent injection attacks from malicious users who are trying to POST data that doesn’t belong.

If we see this exception during the normal execution of an application, the exception is a bad thing. Let’s look at one scenario where the exception can occur after a legitimate postback, and talk about the implementation of event validation. A future post will discuss possible solutions.

Cause

Imagine we’ve been given the task of writing a web form with a DropDownList, and the DropDownList contains three selections.

<h3>Pick Your Favorite Recipe</h3>
<
asp:DropDownList runat="server" ID="_recipeList">
    <asp:ListItem Value="1">
        Amy's Wasabi Encrusted Tuna 
    
</asp:ListItem>
    <asp:ListItem Value="2">
        Big Al's Five Bean Burrito
    
</asp:ListItem>
    <asp:ListItem Value="3">
        Scott's Chocolate Carmel Cheesecake Cookies
    
</asp:ListItem>
</
asp:DropDownList>   

Now, it’s a fairly common scenario for client script to populate the contents of a drop down based upon the value of some other control on the page. For example, a list of states may appear after the user selects a specific country. Let’s simulate that scenario by registering some JavaScript which adds a 4th option to the list.

protected void Page_Load(object sender, EventArgs e)
{
   ClientScript.RegisterStartupScript(
         GetType(),
         
"AddToList",
         script.Replace(
"{_recipeListID}", _recipeList.ClientID),
         
true
      );
}

string script =
  
@"      
     var d = document.getElementById('{_recipeListID}');
     d.options[3] = new Option('George\'s Recipe For Disaster', '4');
   "
;

As long as the user selects recipe 1, 2, or 3, the form will postback without errors. If the user selects option 4, George's Recipe For Disaster, the runtime throws an event validation exception. Disaster indeed!

When ASP.NET rendered the DropDownList it recorded all the possible postback values for the control, It does so by looping through the 3 available ListItems and recording each value. When I say “recorded”, I mean for each item in the list the runtime takes a hash of the control’s UniqueID property, and a hash of the ListItem’s Value property, and XORs the two hash values together. The result of this computation is kept in a list with other allowable hashed values, and the list persists itself as a hidden field in the page.

<input type="hidden" 
       name="__EVENTVALIDATION" 
       id="__EVENTVALIDATION"
       value="/wEWBQKGg9abDQKd9sHMBgKc9s........" 
/>

If the user selects George's Recipe, the browser posts back with a value of “4” for the DropDownList. The runtime will perform the same calculation described earlier:hash(_recipieList.UniqueID XOR hash(“4”)). The runtime will try to find the result of this calculation in the list of allowable values de-serialized from the __EVENTVALIDATION field. The runtime won’t find this value, and will sound the alarm by throwing an exception.

To summarize: the runtime threw an exception because the browser posted a value of “4” for the DropDownList. The runtime thinks the only allowable values are “1”, “2”, and “3”. We added the value “4” as an option using client-side script, so ASP.NET did not know it was legal. ASP.NET calculates the allowable postback values at the last possible moment (inside the Render method of the control).

Just for reference, the following controls support event validation. I’ll provide details on how to know if a control validates events in the next post.

HtmlAnchorHtmlButtonHtmlInputButton
HtmlInputCheckBoxHtmlInputHiddenHtmlInputImage
HtmlInputTextHtmlInputPasswordHtmlInputRadioButton
HtmlInputResetHtmlInputSubmitHtmlSelect
HtmlTextAreaBulletedListButton
CalendarCheckBoxTable
ChildTableWizardChildTableDataControlButton
ImageButtonDataControlImageButtonLinkButton
DataControlLinkButtonDataControlPagerLinkButtonDataGridLinkButton
DetailsViewDropDownListFormView
GridViewHiddenFieldImageMap
LayoutTableListBoxMenu
PagerTableRadioButtonRadioButtonList
TextBoxTreeViewWizardDefaultInnerTable
CatalogZoneConnectionsZoneEditorZone
WebPartZoneZoneButtonZoneLinkButton
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值