【问题标题】:Is it safe to use query string in a post action?在发布操作中使用查询字符串是否安全?
【发布时间】:2013-10-17 12:13:49
【问题描述】:

目前我有两个控制器操作:一个基于唯一标识符显示强类型视图,另一个更改模型。下面是一些代码来可视化我的意思:

[HttpGet]
[ActionName("Edit")]
public ActionResult UpdateDevice(string code)
{
    // Request the device based on the code.
    var device = GetDeviceModel(code);

    // Present the device in a view.
    return View(device);
}

[HttpPost]
[ActionName("Edit")]
public ActionResult UpdateDevice(DeviceModel model)
{
}

代码标识设备,但也可以更改它。这就是我的问题:在 post 方法中,我可以使用 model.Code 访问 new 代码,但我还需要知道 old 代码才能更改它.

我尝试了几种替代方案,但没有一个能满足我的要求:

  • ViewData 在发布之前不会被保留。
  • TempData 基于 Sessions 或 Cookies - 目前我都不想使用它们。
  • 隐藏字段和模型绑定不是一个选项,因为它们可以在客户端进行操作。

最后我尝试从查询字符串中请求数据,如下所示:

[HttpPost]
[ActionName("Edit")]
public ActionResult UpdateDevice(DeviceModel model)
{
    var oldCode = Request.QueryString["code"];
}

这行得通!但是我没有在网上找到任何关于此的资源。所以我的问题是:在 post 操作中使用查询字符串是否可以防止修改?什么(如果有的话)条件是这样的?

如果这不是“记住”代码的有效方式,是否有其他替代方法?

【问题讨论】:

  • 不,修改不安全。
  • 查询字符串不是一个安全的选项。

标签: c# asp.net-mvc http http-post query-string


【解决方案1】:

根据您在问题中提到的要求,您似乎正在寻找安全箱。所以我想说QueryString 不安全。在我看来,使用Session 变量是将关键数据保存在安全位置的适当方法。你可以使用这样的方法

[HttpGet]
[ActionName("Edit")]
public ActionResult UpdateDevice(string code)
{
    Session["code"] = code;
    ....
}

[HttpPost]
[ActionName("Edit")]
public ActionResult UpdateDevice(DeviceModel model)
{
    if (Session["code"] == null)
       throw new Exception("Error Message.");
    var code = Session["code"].ToString();
    ....
    Session["code"] = null;
}      

【讨论】:

  • 尽管这不是我所希望的,但您的回答是最方便的妥协。谢谢!
【解决方案2】:

我认为您可以在 DeviceModel 名称 OldCode 中创建另一个属性。

在您看来,您可以像这样将此值保存在隐藏字段中

@Html.HiddenFor(m=>m.OldCode)

现在在控制器 post 方法中,您可以像这样获取两个值。

[HttpPost]
[ActionName("Edit")]
public ActionResult UpdateDevice(DeviceModel model)
{
    var oldcode=model.OldCode;
    var newcode=model.Code;            
}

希望这会有所帮助...

【讨论】:

  • 抱歉,但“隐藏字段和模型绑定不是一个选项 [...]”,正如我在上面已经说过的那样。
【解决方案3】:

通过 GET 或 POST 请求提交的任何内容都不会被修改。虽然 GET 查询字符串显然很容易修改,但也不需要花费太多精力来欺骗 POST 变量。在我看来,您需要重新考虑您的方法。

您最好在服务器端进行权限检查,以确定是否允许用户使用传递的(旧)代码更新设备。如果他们没有权限,则返回 HTTP 550 代码等错误。

如果您确实不能支持这种方法,我建议按照其他人的建议将“OldCode”字段添加到 DeviceModel 类中,但在将其发送到客户端之前对其进行加密。然后您可以安全地将其写入隐藏字段,并在服务器上解密,而不必担心用户更改值。

【讨论】:

    猜你喜欢
    • 2010-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    相关资源
    最近更新 更多