【问题标题】:Exposing Database IDs to the UI向 UI 公开数据库 ID
【发布时间】:2012-04-05 19:11:53
【问题描述】:

这是一个初学者模式问题,适用于网络表单数据之类的事情。我读了Exposing database IDs - security risk? 并且接受的答案让我认为这是浪费时间,但是等等......

我有一个引用业务逻辑库的 MVC 项目,以及引用相同的 NHibernate SQL 存储库的程序集。如果有什么东西迫使我直接从我的控制器代码库中引用这些存储库,我就会知道出了什么问题。但是,当这些控制器在 URL 参数中与数据库记录 ID 交谈时,是否只是 似乎错了?

我无法想象这些 ID 会变成不可使用的(通过 MVC 操作)。我不认为我需要两个 UI 实体对应于数据库中的同一行。我不打算让控制器以任何方式解释 ID。代理键将产生零差异。尽管如此,我还是想解决这个问题,因为关于理性设计的假设并不比跳层依赖更好。

您将如何制作一个仅引用业务逻辑程序集并在 BL 对象和仅对该会话有意义的 GUID 中进行对话的 Web 应用程序,而该程序集使用数据库 ID 保持事务? p>

【问题讨论】:

    标签: c# sql asp.net-mvc-3 design-patterns


    【解决方案1】:

    您可以根据需要加密或散列您的 ID。使用会话 ID 作为盐。这取决于上下文。您希望目录页面清晰且易于复制的公共购物网站。用户帐户管理员可以对 id 进行加密,因此用户无法通过 url 侵入其他人的帐户。

    我不会认为这是默默无闻的安全。如果恶意用户有一个被盗用的帐户,他们可以查看以该用户身份登录时设置的所有表单字段、url id 和 cookie 值。然后,他们可以在以其他用户身份登录时尝试使用这些来升级权限。但是通过使用会话 ID 作为盐来保护它们,您已经锁定了该数据,因此它仅在一个会话中有用。这些页面甚至无法添加书签。他们能弄清楚你的保护措施吗?可能。但很可能他们只是转移到另一个站点。如果有人想上车,锁上你的车门实际上并不能阻止任何人进入你的车,但它会更难,所以每个人都这样做。

    【讨论】:

    • 你给了我很多思考。您能否就如何实现映射以及将其存储在何处提出任何建议? “会话”确实是 ASP 中最好的地方吗?
    • “映射”?不清楚你在找什么。现场保护?我只是建议你做一个加密函数,它需要:FieldName、FieldValue、SessionID。然后,当您解密时,您还需要提供所有 3 个来解密。因此,另一个会话中的某个人根本无法劫持该值。应该是 url 参数所需的全部内容。如果您需要对无会话页面的支持,您可以使用硬编码值代替会话 ID,虽然安全性不高,但无会话页面不应访问任何敏感内容。
    • 我在你的答案的关键点上进行了讨论,加了会话:根本不需要存储/管理映射——它们会持续很长时间。这太棒了。谢谢。
    【解决方案2】:

    我不是安全专家,但我可以向用户公开某些 ID,例如产品 ID、用户 ID 以及用户通常可以阅读的任何内容,这意味着如果我向用户展示产品,显示其产品 ID 不是问题。

    用户不直接与之交互的系统内部的东西,比如交易 ID,我不向用户显示,不是害怕他们以某种方式编辑它,而是因为那不是有用的信息给他们。

    通常在表单中,我会将操作点指向“mysite.com/messages/view/5”,其中 5 是他们想要查看的消息。在所有这些操作中,我始终确保用户有权查看它(修改或删除,需要任何功能),通过进行简单的数据库检查并确保登录用户相同给消息所​​有者。

    【讨论】:

    • 是的,对 URL 进行模糊处理以不暴露数据库 ID 只是一种通过默默无闻的安全形式。您不应该依赖混淆的 URL 来确保安全。您仍然需要积极实施适合您的应用程序的其他形式的权限管理。
    • 您不应依赖它。但你也不需要为黑客提供便利。
    • 我确实按照这些思路进行了完整性检查:您正在显示第 5 行的所有内容,谁在乎您是否还说“如果您需要知道这是第 5 行”。我的问题主要是这样的:我的视图模型对我的 BL 对象有 1-1,对我的 ORM 实体有 1-1 是巧合,我不想做出约定。
    【解决方案3】:

    要非常非常小心,因为参数篡改会导致数据修改。在公开这些 id 时,必须非常小心地将“谁可以访问哪些 id”的规则构建到您的应用程序中。

    例如,如果您要根据 OrderId 更新订单,请在您的 where 子句中包含用于加载和更新的内容: 其中 order.orderid=passedInOrderId 和 Order.CustomerId=

    我开发了一个扩展来帮助在 MVC 中存储 id 可用这里:

    http://mvcsecurity.codeplex.com/

    我还在我的安全课程中谈到了这一点:Hack Proofing your ASP.NET MVC and Web Forms Applications

    【讨论】:

    • 您的 codeplex 项目看起来与我们在这里使用的技术非常相似。但是我们不使用机器密钥,我们使用来自数据库支持的会话的密钥,因此它适用于所有不同的 ui 层框。对于那些认为他们永远不会有任何忽略完美用户访问验证的错误的人,我感到相当惊讶。那不是真实的世界。
    • 好建议,它将在 BL 中进行权限/角色检查,并在真实 ID 中运行。
    【解决方案4】:

    除了这些响应之外,有时最好使用明显的 id,这样人们就可以破解 url 以获得他们想要的信息。例如,www.music.com\artist\acdc 或 www.music.com\arist\smashing-pumpkins。如果它对您的用户有意义,并且如果您可以通过 URL 增加用户从页面中理解的信息,那就更好了,特别是如果您的细分市场年轻或精通技术,那么使用 id 对您有利。这也将提高您的搜索引擎优化。 我会说当它没有用时,然后对其进行编码。一个开发人员只需要一个错误就不会根据会话检查客户 ID,并且您会暴露整个客户群。

    但是,当然,您的单元测试应该能够捕捉到这一点!

    【讨论】:

    • 这是另一件需要考虑的事情——信息丰富且清晰易读或临时且无意义都是好的,但我继续觉得从数据库继承的只是因为不是;关于如何实际实现任何一种映射的任何建议?我认为只是数据库中的一列便于用户使用
    • 哦,我明白了。你的意思是粉碎南瓜到 1456789 的映射。我认为它必须是数据库中的另一列。但是我看到的大多数 mvc 示例只是到处使用标识整数。问题是 1456789 是自动生成的,保证唯一。您尝试对其他有意义的字段之一执行的任何操作都可能不是唯一的,如果它不是唯一的,则尝试将其用于查询是没有好处的。除非你做类似hotmail、smasing-pumpkins、smasing-pumpkins8973232等的事情。
    【解决方案5】:

    虽然您会发现有些人说 ID 只是实现细节,但在大多数系统中,您需要一种唯一标识域实体的方法,并且很可能会为该标识符生成一个 ID。 ID 由数据库生成这一事实是一个实现细节;但是一旦生成,它就成为域实体的属性,因此在需要引用实体的任何地方使用它是完全合理的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 2019-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多