【问题标题】:Query String Parameters make my app at risk?查询字符串参数使我的应用程序处于危险之中?
【发布时间】:2010-02-01 15:19:54
【问题描述】:

我正在编写一个 Asp.Net WebForms 应用程序,我在其中调用一个编辑页面,并使用 URL 中的查询字符串参数传入有关要编辑的记录的数据。

喜欢:

http://myapp.path/QuoteItemEdit.aspx?PK=1234&DeviceType=12&Mode=Edit

在应用程序的上一个页面上,我已经向用户展示了一个他可以根据他的帐户权限编辑的筛选项目的 GridView,我使用上述参数列表调用编辑页面,页面知道该做什么.我不会在目标页面上做任何额外的检查来验证用户是否可以访问传入的 PK 记录值,因为我计划依靠上一页来过滤列表,我会没事的。

但是,很明显,用户现在可以输入不同 PK 的 URL 并获得编辑该记录的权限。 (或者,他可能有权访问 Mode=View,但不能访问 Mode=Edit 或 Mode=Delete。基本上,我希望避免验证目标页面上的记录和访问权限。

我还测试了相同的工作流程,使用 Session 变量在调用目标页面之前存储 PK、DeviceType 和 Mode,然后从目标页面中的 Session 中读取它们。因此不涉及查询字符串参数。这将使用户失去控制权。

因此,我正在寻找有关这两种方法的反馈,以便我选择一种公认/标准的方式来处理这个问题,因为这似乎是 CRUD 应用程序的一种非常常见的应用程序设计模式。

【问题讨论】:

  • 感谢所有回答的人。显然,100% 的共识是您必须验证目标页面的访问权限,即使之前的工作流程已被设计为限制用户可以看到/执行的操作。我必须学会欣赏这种谨慎的态度。
  • 遗憾的是,我只能将一个答案标记为已接受,但几乎任何一个答案都可以标记为已接受。

标签: asp.net parameters query-string


【解决方案1】:

同意,您需要验证目标页面上的权限,这是绝对确定的唯一方法。谈到安全性,冗余并不是一件坏事。像不信任业务层一样保护您的数据库,像不信任 UI 一样保护您的业务层,同时保护 UI。

【讨论】:

  • 同意,没有“足够安全”之类的东西。甚至不要完全信任其他代码,因为有时可能会有一个无能(或恶意)的程序员在更高层之一进行一些更改(即在我们的应用程序中,输入是(可悲的)在开头的 sql 转义脚本并且碰巧需要一个值而不转义,因此(再次:可悲的)全局变量未转义......为SQL注入打开了一个洞(因为数据库层不再检查,猜测之前一切都被转义了) )。偏执会有所帮助。
【解决方案2】:

您应该始终在实际执行操作之前进行验证,尤其是在通过查询字符串传递参数时。对于执行执行的第二个页面,您可能不需要为用户提供太多反馈,因为如果他试图绕过您的安全性,您不必对用户友好,因此错误处理应该容易得多。

在每个会话中传递变量是可以接受的但是恕我直言,您仍然应该验证这些值。

【讨论】:

    【解决方案3】:

    我们总是使用查询字符串,因此可以轻松地为记录添加书签,但是始终在两个地方都进行验证,如果您编写的访问控制代码很好,它应该只是重复使用现有代码的情况......

    【讨论】:

      【解决方案4】:

      我认为通常的做法是做您要避免的事情:在原始页面上,您需要检查用户应该具备哪些能力,并适当地显示他们的选项。然后在实际工作页面上,您需要再次检查用户以验证他们是否被允许在那里,并且可以访问该特定任务。

      从可用性的角度来看,这是用户想要的(保持简单,允许他们为某些页面添加书签等),并且两个页面的安全性是做到这一点的唯一方法。

      【讨论】:

        【解决方案5】:

        如果你真的不想检查目标页面的访问权限:

        您可以使用 UserID 对 PK 进行哈希处理,然后将哈希值添加到查询字符串中。

        string hash = hashFunction(PK.toString() + UserID.toString());
        

        然后您必须确保 queryString 中的哈希值等于加载页面之前计算的哈希值。

        假设这是一个内部组织的 Web 应用程序。

        【讨论】:

        • 这是一个面向公众的网站,但不向公众开放。我们只向我们的客户发布登录名和密码,因此您可以称之为“仅限邀请”。该域托管在托管公司服务器上,如果您知道 URL,您可以直接浏览它,然后您将点击登录页面。然而,这有什么关系呢?无论是公开的还是内部的,您的建议似乎都恰如其分。
        • 我只是想说明这个解决方案对于内部应用程序来说可能已经足够了。向全世界公开的页面可能需要额外的安全措施,而不仅仅是哈希检查。
        【解决方案6】:

        会话变量也可以被操纵,虽然不是那么容易。无论您在整个站点中使用什么身份验证,您都应该在目标页面上使用。否则,您可能会像您发现的那样公开您可能不想要的数据。

        【讨论】:

        • 您有关于用户如何更改会话变量的链接吗?我没听说过这个
        • 会话变量实际上只是一个会话范围的 cookie。使用 Firebug for Firefox 并转到 Cookies > 查看 Cookie 信息。从这里您可以编辑当前站点的任何 cookie。
        • 您只收到了两个cookie:一个用于sessionId(不包含任何值),另一个用于表单身份验证......两者都是加密的。您将如何更改客户端上不存在的值?
        【解决方案7】:

        您可以执行以下操作以使您的网址更加安全:

        -使用 Guids 作为主键,因此用户无法猜测其他记录 ID

        -模式可以是隐式的:Guid = Edit,没有 Guid = New

        和..

        -服务器端验证是唯一的方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多