假设我的路由看起来像/controller/action/UserID
接受POST。
然后假设有人POST到该URL,并将一个名为UserID的变量设置为其他内容。
我想弄清楚的是,是否有可能出现安全问题,一个值“潜行”超过我的许可检查。
答案 0 :(得分:1)
参数源优先级的顺序由ValueProviderFactories.Factories
集合确定,其中(默认情况下)POST-ed参数优先于模型绑定期间的路径数据。
因此,如果您的控制器/controller/action/777
中的UserId
网址发布了UserId = 666,则为666。
本文的Value Providers部分概述了其工作原理:
在运行时,ASP.NET MVC使用在中注册的值提供程序 ValueProviderFactories类用于评估模型的请求值 粘合剂可以使用。
默认情况下,值提供程序集合会评估值中的值 各种来源按以下顺序排列:
- 以前绑定的动作参数,当动作是孩子时 行动
- 表单字段(
Request.Form
)- JSON中的属性值 请求正文(
Request.InputStream
),但仅在请求是的时候 AJAX请求- 路线数据(
RouteData.Values
)- 查询字符串参数 (
Request.QueryString
)- 已发布文件(
醇>Request.Files
)
答案 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.Form
或model
中的值),那么参数优先级是什么并不重要。您应该验证当前登录用户是否有权在您的控制器POST方法中查看或编辑userId
的ID,因为无论如何都无法信任所有客户端提供的参数。
e.g。
[HttpPost]
public ActionResult Foo(model model, int userId)
{
if (CurrentUserHasPermissionToEdit(userId))
{
// Do stuff
}
else
{
// Reject
}
}