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

C# 在.NET中,如何防止或处理在提交前篡改禁用字段的表单数据?,c#,asp.net,firebug,dynamic-forms,C#,Asp.net,Firebug,Dynamic Forms,如果禁用的下拉列表被动态呈现到页面中,仍然可以使用Firebug或其他工具篡改提交的值,并删除“禁用的”HTML属性。 此代码: protected override void OnLoad(EventArgs e) { var ddlTest = new DropDownList() {ID="ddlTest", Enabled = false}; ddlTest.Items.AddRange(new [] { new ListItem("Please select", "")

如果禁用的下拉列表被动态呈现到页面中,仍然可以使用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>

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

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


我认为蛮力方法是垃圾,比如在OnLoad中保存正确的值,然后在OnPreRender中恢复值。由于某些字段依赖于其他字段,这对我来说是不可接受的。

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

编辑
这对于客户端篡改是安全的,因为禁用的控件永远不会由表单提交,因此修改后的数据永远不会到达服务器。请参阅。

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

编辑
这对于客户端篡改是安全的,因为禁用的控件永远不会由表单提交,因此修改后的数据永远不会到达服务器。请看。

不要处理这些数据,你会做得很好的。如果您正在显示一些常量,那么它们应该存储在服务器端。

只要不处理这些数据,就可以了。如果要显示某些常量,则应将其存储在服务器端。

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


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

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


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

使用ViewState。它的加密程度足以阻止普通黑客。

使用ViewState。它的加密程度足以阻止普通黑客。

回顾一些老问题,我意识到至少存在一种简单的方法:使用@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属性没有呈现给客户端,那就好了。我想这就是这个解决方案所代表的骇客近似值。

回顾一些老问题,我意识到至少存在一种简单的方法:使用@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属性没有呈现给客户端,那就好了。我想这就是这个解决方案所代表的黑客近似值。

用标签替换输入字段


换句话说,与其禁用文本框或下拉列表,不如隐藏它们并显示标签

用标签替换输入字段


换句话说,与其禁用文本框或下拉列表,不如隐藏它们并显示标签

很难(实际上不可能)从客户端更改服务器状态(
Session
state)。“我希望如此。”安德斯:那没关系。禁用的控件永远不会由表单提交,因此修改后的数据永远不会到达服务器。请看。谢谢你的澄清和链接-我学到了一些新东西。@Anders:不用担心-这在我第一次看到它时也让我很惊讶。我一直认为所有的值都被传递到服务器,并且禁用
只是一个UI问题,但将其留给20分钟的调试会话来了解真正发生了什么!:)关键是Firebug可以用来删除disabled属性,因此客户机会提交该值。此外,会话不是一个选项,因为服务器集群上没有会话关联。很难(实际上不可能)从客户端更改服务器状态(
session
state)。“我希望如此。”安德斯:那没关系。禁用的控件永远不会由表单提交,因此修改后的数据永远不会到达服务器。请看。谢谢你的澄清和链接-我学到了一些新东西。@Anders:没有