Php 通过哈希键保护URL参数安全吗?

Php 通过哈希键保护URL参数安全吗?,php,security,Php,Security,我想让用户在他们的帐户之外共享数据,并将概念证明放在一起,基本上生成一个具有相关URL参数的唯一URL来显示数据 显然,普通URL只允许您修改参数、修改查询并提取所需的任何数据。因此,当用户生成共享数据的链接时,我会获取参数,添加一个复杂的salt,对组合字符串(sha-2)进行散列,然后将其用作密钥。因此,URL可能如下所示: mydomain.com/app/shared.php?function=form&account=1&form=a19481e78dd87f5eb04afe94c85

我想让用户在他们的帐户之外共享数据,并将概念证明放在一起,基本上生成一个具有相关URL参数的唯一URL来显示数据

显然,普通URL只允许您修改参数、修改查询并提取所需的任何数据。因此,当用户生成共享数据的链接时,我会获取参数,添加一个复杂的salt,对组合字符串
(sha-2)
进行散列,然后将其用作密钥。因此,URL可能如下所示:

mydomain.com/app/shared.php?function=form&account=1&form=a19481e78dd87f5eb04afe94c85ea4f3&key=7dcaa38baa19e0f70262d8775582300346f5c544

输入URL后,服务器将重新编译参数和秘密salt,并验证密钥。如果密钥无效,则不显示任何数据

我确实考虑过通过将参数存储在DB中来进一步保护这一点,因此URL看起来更像
mydomain.com/app/h6Hs52ff2a
,并且参数从未直接包含在URL中,但同样,我非常喜欢在没有DB后端的情况下动态生成可共享URL的想法

我觉得上面的方法可能有点不受欢迎,但同样,除非您知道服务器上存储的salt(它本身很复杂),否则我看不到任何绕过这样一个系统的方法


想法最受欢迎。

这是一个完全可行的方法,本质上是一个签名URL。该系统唯一的弱点是盐/钥匙的保密性;如果您使用的是快速散列/加密算法和弱salt/密钥,则可以在脱机情况下强制执行秘密。因此,您需要使用足够强(读:慢)的算法来防止这种情况(普通的SHA2太快了!),并且您需要确保您的密钥不会泄漏。您还需要确保不会意外丢失密钥,因为这会重置所有共享URL。如果这是正确的,这是一个很好的,无状态的方式做事情

我会考虑作为您自己开发的方法的替代方法,因为它们基本上已经包含了您的所有需求(它们基本上是任意签名的数据包)

数据库方法的优点是它没有攻击面,并且可以有选择地使共享URL无效。缺点是它使用数据库存储,这可能会带来操作开销


这里的另一个决定性因素是URL长度,您可能会关心,也可能不关心。

如果您需要保证,这与Google Drive在与链接共享文档时使用的概念相同

一些评论:

  • 共享链接可读性。如果共享数据总是关于相同类型的模型(例如帐户数据),则链接正常。但是,如果可以共享其他类型的数据,比如用户详细信息,我会将其包含在URL中,以便获得共享链接的人能够理解该链接
  • 如果您想增加更多的安全性,可以对每个用户强制执行密钥。您需要在数据库中为每个用户保留密钥
  • 生成url时,添加到期参数和哈希。在读取散列链接时,您可以查看链接是否过期
  • 确保使用URL安全字符

看着你正在努力实现的目标,我想知道,你为什么不干脆:

  • 每当用户希望共享URL时,将数据库中的128位随机值映射到一组表单参数。它与您使用的随机数生成器一样安全,表单值仍然是一个秘密(因为它们永远不会离开服务器)
  • 使用带有消息身份验证的密码对参数进行加密(使用GCM或OCB等模式进行身份验证加密)。除非你的钥匙漏了,否则要小心。对用户的眼睛隐藏表单参数
  • 仅使用“已验证加密”的一部分,如消息验证码(MAC;HMAC)。不隐藏表单参数,添加需要验证的代码

谢谢您的建议和考虑。在我看来这是有道理的,但是有你的想法很好。DB后端确实很有意义——特别是在控制和撤销访问方面,但正如您所说的,它有潜力快速增长。我已经实现了数据“非共享”的功能,但它是在记录级别实现的,而不是记录已共享和未共享内容的单独表。如果您的参数包含对数据库中某些数据的引用,则无法在没有数据库后端的情况下生成可共享URL。您应该检查生成URL的用户是否有权访问引用的对象。因此,第二种方法似乎更好,因为它可以让您更好地控制生成的URL。如果参数直接包含数据而不是引用,那么是否需要保护它们?当有人修改params中的数据时,他只会得到乱七八糟的结果,所以可能没有真正的动机来修改params。