先例:使用相同的名称路由值或表单POST?

时间:2013-11-25 21:03:28

标签: asp.net-mvc security asp.net-mvc-4 post

假设我的路由看起来像/controller/action/UserID接受POST。

然后假设有人POST到该URL,并将一个名为UserID的变量设置为其他内容。

我想弄清楚的是,是否有可能出现安全问题,一个值“潜行”超过我的许可检查。

2 个答案:

答案 0 :(得分:1)

参数源优先级的顺序由ValueProviderFactories.Factories集合确定,其中(默认情况下)POST-ed参数优先于模型绑定期间的路径数据。

因此,如果您的控制器/controller/action/777中的UserId网址发布了UserId = 666,则为666。

本文的Value Providers部分概述了其工作原理:

  

在运行时,ASP.NET MVC使用在中注册的值提供程序   ValueProviderFactories类用于评估模型的请求值   粘合剂可以使用。

     

默认情况下,值提供程序集合会评估值中的值   各种来源按以下顺序排列:

     
      
  1. 以前绑定的动作参数,当动作是孩子时   行动
  2.   
  3. 表单字段(Request.Form
  4.   
  5. JSON中的属性值   请求正文(Request.InputStream),但仅在请求是的时候   AJAX请求
  6.   
  7. 路线数据(RouteData.Values
  8.   
  9. 查询字符串参数   (Request.QueryString
  10.   
  11. 已发布文件(Request.Files
  12.   

答案 1 :(得分:1)

无论参数优先级如何,您都应该检查用户是否有权访问所有POST以及GET上的指定UserID

用户可以轻松地隐藏额外的UserID参数,因为将表单action更改为路径中具有不同UserID的网址,因为这些只是客户端变量。

<form method="post" action="/controller/action/1">

可以轻松更改为

客户端

<form method="post" action="/controller/action/2">

这就像添加隐藏字段一样简单:<form method="post" action="/controller/action/1"> <input type="hidden" name="UserID" value="2" />

如果您的控制器方法签名是

[HttpPost]
public ActionResult Foo(model model, int userId)

您只在输入参数中使用userId(例如,不直接访问Request.Formmodel中的值),那么参数优先级是什么并不重要。您应该验证当前登录用户是否有权在您的控制器POST方法中查看或编辑userId的ID,因为无论如何都无法信任所有客户端提供的参数。

e.g。

[HttpPost]
public ActionResult Foo(model model, int userId)
{
    if (CurrentUserHasPermissionToEdit(userId))
    {
      // Do stuff
    }
    else
    {
      // Reject
    }
}