views:

111

answers:

4

Hi,

If a disabled drop-down list is dynamically rendered to the page, it is still possible to use Firebug, or another tool, to tamper with the submitted value, and to remove the "disabled" HTML attribute. This code:

protected override void OnLoad(EventArgs e) {
    var ddlTest = new DropDownList() {ID="ddlTest", Enabled = false};
    ddlTest.Items.AddRange(new [] { new ListItem("Please select", ""), new ListItem("test 1", "1"), new ListItem("test 2", "2") });
    Controls.Add(ddlTest);
}

results in this HTML being rendered:

<select disabled="disabled" id="Properties_ddlTest" name="Properties$ddlTest">
    <option value="" selected="selected">Please select</option>
    <option value="1">test 1</option>
    <option value="2">test 2</option>

</select>

The problem occurs when I use Firebug to remove the "disabled" attribute, and to change the selected option.
On submission of the form, and re-creation of the field, the newly generated control has the correct value by the end of OnLoad, but by OnPreRender, it has assumed the identity of the submitted control and has been given the submitted form value.
.NET seems to have no way of detecting the fact that the field was originally created in a disabled state and that the submitted value was faked. This is understandable, as there could be legitimate, client-side functionality that would allow the disabled attribute to be removed.

Is there some way, other than a brute force approach, of detecting that this field's value should not have been changed?

I see the brute force approach as being something crap, like saving the correct value somewhere while still in OnLoad, and restoring the value in the OnPreRender. As some fields have dependencies on others, that would be unacceptable to me.

+2  A: 

If this is truly a concern then persist a value on the server somewhere (in session perhaps) that indicates that the control was set as disabled on the initial render of the page. If the control is not still in a disabled state when the page posts back then you know the form was tampered with.

Edit

This is secure against client tampering because a disabled control is never submitted by the form and as such the modified data will never reach the server. Please see http://w3.org/TR/html401/interact/forms.html#h-17.12.

Andrew Hare
It's hard (practically impossible) to change server state (`Session` state) from the client-side. I hope.
Jeremy McGee
@Anders: That doesn't matter. A disabled control is never submitted by the form and as such the modified data will never reach the server. Please see http://www.w3.org/TR/html401/interact/forms.html#h-17.12.
Andrew Hare
@Andrew: Thanks for clarifiying and for the link - I've learnt some new things.
Anders Abel
@Anders: No worries - that surprised me too the first time I saw it. I always assumed that all values were passed to the server and that `disabled` was simply a UI thing but leave it to a 20-minute debugging session to learn what was really going on! :)
Andrew Hare
The point is that Firebug can be used to remove the disabled attribute, so the client DOES submit the value. Also, session is not an option, as there is no session affinity on the cluster of servers.
David
A: 

Just dont process that data and you would do fine. If you are displaying some constants then they should be stored server side.

Aseem Gautam
This doesn't answer the question in a non-trivial way at all. I think you're just looking for points.
David
Yes it does. @you: The point is that Firebug can be used to remove the disabled attribute, so the client DOES submit the value. Also, session is not an option, as there is no session affinity on the cluster of servers. || @Me:Now even if it does submit the control, why are you even processing its value. Any values which are not supposed to be changed client side should be kept server side.
Aseem Gautam
How is your answer non-trivial? Does it give any advice about HOW to detect which data to not process? Where in the event time-line to hook in? Any neat tricks to use? Anything? "Just dont process that data..." No kidding. Mind telling .NET that?
David
+1  A: 

A general rule for building secure webb applications: Don't ever trust any input from the client. Assume that each request has been handbuilt in order to break through your security system.

The only thing safe is to ignore any data coming back from the disable fields. That data will have to be stored in the session, or reloaded from the database (or whatever data storage you use).

Anders Abel
The problem is knowing when a field is disabled, as the form is generated dynamically from .NET controls.
David
A: 

Use ViewState. It is encrypted enough to stop the average hacker.

Mark Hurd