在 .NET 中,如何在提交之前防止或处理禁用字段的表单数据被篡改?

发布于 2024-08-27 23:55:37 字数 1034 浏览 12 评论 0原文

如果禁用的下拉列表动态呈现到页面,仍然可以使用Firebug或其他工具来篡改提交的值,并删除“禁用”的HTML属性。 此代码:

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);
}

导致呈现此 HTML:

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

当我使用 Firebug 删除“禁用”属性并更改所选选项时,会出现问题。
提交表单并重新创建字段时,新生成的控件在 OnLoad 结束时具有正确的值,但通过 OnPreRender,它已假定提交的控件的标识并已被赋予提交的表单值。
.NET 似乎无法检测该字段最初是在禁用状态下创建的,并且提交的值是伪造的。这是可以理解的,因为可能有合法的客户端功能允许删除禁用的属性。

除了暴力方法之外,是否有其他方法可以检测到该字段的值不应被更改?

我认为暴力方法很糟糕,比如在 OnLoad 中将正确的值保存在某个地方,然后在 OnPreRender 中恢复该值。由于某些领域依赖于其他领域,这对我来说是不可接受的。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

凡间太子 2024-09-03 23:55:37

如果这确实是一个问题,则在服务器上的某个位置(可能在会话中)保留一个值,该值指示该控件在页面的初始呈现时被设置为禁用。如果页面回发时控件并未仍处于禁用状态,那么您就知道表单已被篡改。

编辑

这可以防止客户端篡改,因为表单永远不会提交禁用的控件,因此修改后的数据永远不会到达服务器。请参阅http://w3.org/TR/html401/interact/ forms.html#h-17.12

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.

遗失的美好 2024-09-03 23:55:37

使用视图状态。它的加密程度足以阻止普通黑客。

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

離人涙 2024-09-03 23:55:37

构建安全 Webb 应用程序的一般规则:永远不要信任来自客户端的任何输入。假设每个请求都是手工构建的,以便突破您的安全系统。

唯一安全的是忽略从禁用字段返回的任何数据。该数据必须存储在会话中,或从数据库(或您使用的任何数据存储)重新加载。

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).

一指流沙 2024-09-03 23:55:37

回顾一些老问题,我意识到至少存在一种简单的方法:使用 @Mark Hurd 提到的页面视图状态。

这是一个快速破解,但类似这样的事情:

    private const string defaultValue = "Hack me!"; // from original data source
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        ViewState[txtTest.ClientID] = false;
    }
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if(ViewState[txtTest.ClientID] != null && !(bool)ViewState[txtTest.ClientID])
            txtTest.Text = defaultValue;

        string x = txtTest.Text;
    }

我什至不记得我在解决这个问题时做了什么...无论如何,如果有一个未渲染的表示“真正禁用”的.NET属性,那就太好了给客户。我想这就是这个解决方案所代表的黑客近似。

Going back through some old questions, I realised at least one simple approach exists: Use the page's viewstate as mentioned by @Mark Hurd.

This is a quick hack, but something like this:

    private const string defaultValue = "Hack me!"; // from original data source
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        ViewState[txtTest.ClientID] = false;
    }
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if(ViewState[txtTest.ClientID] != null && !(bool)ViewState[txtTest.ClientID])
            txtTest.Text = defaultValue;

        string x = txtTest.Text;
    }

I can't even remember what I was doing with this problem... Anyway, it would be good if there was a .NET attribute meaning "really disabled" that wasn't rendered to the client. I guess that's what this solution represents a hack-approximation of.

享受孤独 2024-09-03 23:55:37

只要不处理这些数据就可以了。如果您要显示一些常量,那么它们应该存储在服务器端。

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

欢烬 2024-09-03 23:55:37

用标签替换输入字段。

换句话说,无需禁用 TextBox 或 DropDown,只需隐藏它们并显示标签即可。

Replace the input fields with labels.

In other words, instead of disabling a TextBox or DropDown, just hide them and show a label instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文