【问题标题】:ASP.NET Model Id in ViewModel - is it safe?ViewModel 中的 ASP.NET 模型 ID - 安全吗?
【发布时间】:2016-11-30 19:24:46
【问题描述】:

场景: (使用 ASP.NET Web 应用程序 - Core 或 MVC)

我有一个数据库,每个用户都有UsersItems。 这意味着UserIdforeign keyItems 表中。

我在浏览器中以User 的身份登录。我将Items 作为ItemViewModels 的列表,通过一个简单的api GET 请求映射(AutoMapper)到ItemViewModels

我想通过一个简单的 API 调用更新其中一个项目(应该属于我 - 已登录的用户)。因此,我通过 PUT 请求将修改后的项目作为 ItemViewModel 发送回服务器。

第一种方法:

最简单的方法是在 ItemViewModel 中包含项目的数据库 ID ItemId - 所以当我收到要更新为 ItemViewModel 的项目时,我可以将其映射回现有项目数据库。

但这对我来说听起来很不安全,因为任何人都可以使用任何ItemId 修改 PUT 请求并影响不属于执行请求的用户的项目。我对这种方法有什么遗漏吗?

第二种方法:

不要在ItemViewModel 中传递数据库PK ItemId。 而是使用其他形式的标识:假设用户 X 有 10 个项目。它们使用名为UserItemId(也存在于数据库中)的属性从1 到10 编号。

然后我可以在ItemViewModel 中传递这个UserItemId,当我取回它时,我可以将它映射到数据库中的现有项目(如果请求一切正常)或丢弃它并拒绝请求,如果UserItemId 与登录用户项目中的任何内容都不匹配。

有人使用这种方法吗?

优点

用户只能访问自己的项目,不能影响其他任何人,因为它不知道实际的项目 ID(主键),并且任何修改都仅限于自己的项目。

缺点

必须在服务器端实施大量额外管理才能使这种方法发挥作用。

还有其他方法吗?

请考虑上面提到的情况适用于数据库中客户端实现可以 CRUD 的所有实体,所以它不仅仅是上面描述的简单情况。

建议的解决方案应该适用于整个应用数据。

我知道有人问过这个问题 herehere 但第一个问题没有令人满意的答案,我认为第二个问题并不真正适用于我的情况,因为它只涉及 UserId .

谢谢。

编辑

请将上面的Item 视为一个聚合根,其中包含多个复杂的subItems,每个在数据库中都有一个表。这个问题适用于他们和主要的Item。这意味着每个 subItem 都作为 ViewModel 传递给客户端。

我应该提到关于进一步保护更新请求:

  1. 对于第一种方法,我可以轻松检查是否允许用户更改项目。但我也应该为所有subItems 这样做。

  2. 对于第二种方法,我可以检查用户是否可以更新 Item,如下所示:我得到传入 ViewModel 的 userItemId -> 我从数据库中获取所有登录用户的项目并尝试找到与相同userItemId 匹配的匹配项,如果我成功了,我会继续更新。

【问题讨论】:

  • 永远不要相信用户输入。您必须始终在服务器上进行验证。检查当前用户是否有权根据 ID 更新对象,如果有,则执行更新(否则重定向到错误页面)

标签: asp.net-mvc security model mapping viewmodel


【解决方案1】:

如果您只隐藏 ID,我认为您的应用程序不安全。 在更改数据库实体之前,您必须检查是否允许用户更改实体。 在您的情况下,您应该检查来自经过身份验证的用户的Id 是否是您项目中的UserId。 如果您的 ViewModel 与您的 API 相似或相同,您可以在控制器中使用 FilterAttribute。

【讨论】:

    猜你喜欢
    • 2011-10-19
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    相关资源
    最近更新 更多