【问题标题】:Modifying item in viewstate - is it safe to do?修改视图状态中的项目 - 这样做安全吗?
【发布时间】:2013-08-01 16:10:44
【问题描述】:

我仍然是一个相对的菜鸟,但是我对我所做的一个小测试的结果感到惊讶。

我想在视图状态中存储一个字符串列表。迄今为止,当我想修改列表时,我从 viewstate 中检索了它,执行了 List.Add 并将其保存回 viewstate。

不过,我决定做一个简单的测试,如下:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            List<string> s = new List<string>();
            s.Add("abc");
            s.Add("def");
            ViewState.Add("test", s);

            s.Add("one");
            s.Add("two");
        }
        var t = (List<string>)ViewState["test"];

        foreach (var str in t)
        {
            Response.Write(str + "<br>");
        }
    }

如您所见,我创建了一个列表,将其添加到 viewstate,然后修改该列表。令我惊讶的是,即使在回发之后,列表也会在 viewstate 中进行修改。

问题是,这样做是否安全,如果是,是否被认为是不好的做法。

提前致谢。

【问题讨论】:

    标签: asp.net viewstate


    【解决方案1】:

    ViewState 仅在回发时序列化到客户端页面。 在此之前,它保存在内存中并且可以安全地进行编辑。

    我经常使用 ViewState 作为属性的支持者:

    public Class1 MyClass1
    {
        get { return (Class1)ViewState["MyClass1"]; }
        set { ViewState["MyClass1"] = value; }
    }
    

    一般来说,我不会认为这样做是不好的做法,但以下情况除外:

    1. 存储敏感数据 - 由于数据被序列化到客户端,因此很容易被更改。
    2. 大量数据 - 由于数据被持久化到客户端,因此大量数据会显着增加页面加载时间。

    【讨论】:

    • 我实际上认为这是不好的做法;除非您采取其他步骤,否则视图状态可能会被篡改,这可能会导致安全问题。此外,您发送的越多,您在响应中返回的数据就越多,从而增加了页面的加载时间。
    • @Andy 对于大量数据或敏感数据,您是绝对正确的。然而,这个问题似乎更具体到编辑视图状态数据,而不是什么类型的数据可以存储在那里。
    【解决方案2】:

    您看到此问题的原因是 Asp.Net WebForms page life cycle。在您修改视图状态时,Asp.Net 尚未将页面输出呈现为 HTML。由于您要添加对字典的引用,因此您在渲染之前所做的更改将会显示出来。生命周期中的其他点可能不会出现此类更改,尽管我没有调查过是否是这种情况。

    但是,我不会考虑这种好的做法。 ViewState 在您的网页中被序列化为隐藏的表单字段,因此其中的任何数据都是您页面的一部分。这充其量只能增加发送给客户端的响应的大小(如果您在那里存储大量数据,有时会显着增加)。由于是隐藏的表单域,所以返回服务器的请求也比较大。

    它还可以打开安全漏洞。你不能信任必须信任视图状态,尽管有一些方法可以secure it,但我会说最好不要发送任何你绝对不需要渲染页面的数据。

    作为替代方案,您可以考虑将特定于用户的状态存储在 Session 中,但如果您的应用程序将位于网络场中的负载平衡器后面,您确实需要付出一些额外的努力。将数据存储在会话中将使其与其他用户隔离,并且根本不需要将数据暴露给客户端。

    【讨论】:

      【解决方案3】:

      有点主观,但通过实践我看不出有什么问题。这是页面上不同表单控件中一直发生的事情。控件将编辑与它们自己相关的视图状态信息,并将其保留在回发中。将列表添加到视图状态后对其进行修改时,列表在视图状态中发生更改的原因是它不会立即序列化。该列表通过引用传递给它所在的视图状态集合,直到页面在完成请求前不久序列化视图状态。

      【讨论】:

      • 非常有用 - 现在我明白为什么会发生这种情况,因此可以确定何时可以接受和不接受这种方式。
      • 虽然在视图状态中存储数据会有一些严重的后果,所以我认为说“这没有什么问题”并不准确。控制状态是一回事,因为用户几乎可以直接更改控制状态,但任意数据是另一回事。
      • @dotnetnoob 请注意,在 ViewState 中存储数据可能会产生一些负面影响;正如这个答案所说,它并不总是安全或一个好主意。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 2010-12-29
      • 2017-09-11
      • 1970-01-01
      相关资源
      最近更新 更多