显然,取决于返回到Web前端的数据的类型/上下文(在我的情况下,设置是HTML / Javascript,.NET Csharp后端和JSON作为数据传输),如果我必须返回ID说自动生成的主键消息(Int64),“隐藏”这个真实ID的最佳方法是什么?
对于大多数事情当然,我可以理解它没有太大区别,但是我正在处理的应用程序意味着如果用户“猜到”URL中的ID以撤回另一条记录,它可以证明是一个安全问题..
似乎有很多关于方法的想法/评论,但没有一点点击。
我正在考虑使用自动生成的主要INT,但也考虑使用辅助备用GUID。这将是GUID返回到任何前端进程,当然自动生成的主ID仍将在后端使用..
当然,想到GUID会更难以猜测/获得另一个访问记录吗?
人们使用的任何想法或最佳做法?
提前致谢, 大卫。
答案 0 :(得分:2)
我正在努力意味着如果用户“猜到”网址中的ID以撤回另一条记录,则可能会证明这是一个安全问题。“
如果是这种情况,那么您真的需要退一步并检查安全方法。如果用户可以访问他们无权查看的记录,则无法提供对象参考的适当安全性 - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References
GUID方法将尝试通过默默无闻提供安全性,请参阅Is using a GUID security though obscurity?是否确实如此,您必须根据自己的情况自行决定。
答案 1 :(得分:2)
关于安全性,您有几个方面:
处理这些问题的措施取决于您的架构和安全需求。
由于您没有详细说明您的架构和安全需求,因此很难提供任何具体的建议......
关于“ID不应该被猜测”的一些观点:
“正确”解决方案
在您正确实施身份验证+ autherization的那一刻,问题就消失了
因为正确实现了这两个,请确保只有经过身份验证的用户才能访问
任何事情,每个用户只能访问他被允许的事情。即使经过身份验证的用户知道他不被允许访问的内容的正确ID也是安全的,因为他将无法访问它。
“弱解”
创建一个ConcurrentDictionary
作为线程安全的内存缓存,并将真实ID加上“临时ID”(例如,在第一次记录访问时新生成的GUID)。您可以将该临时ID与某些连接特定方面(如客户端IP,时间等)的某些盐和/或加密和/或散列相结合。然后在每次访问时使用ConcurrentDictionary进行检查并相应地执行...一个正面效果:在应用程序重新启动后(例如应用程序池回收),相同的记录获取不同的ID,因为这只是一个内存缓存...虽然这在网络农业场景中几乎无法使用
答案 2 :(得分:1)
从技术上来说,通过查询另一个ID来撤回另一条记录是一件坏事 - 只有当其他ID对于将其拉回的用户不可见时才是这样。但是,无论如何你都有安全问题,你应该专注于那个而不是找到一种方法来模糊ID
无论如何,如果你想弄乱网址,我建议你调查Rijndael。我们在这里使用它来传递令牌。基本上,这种加密技术允许您加密和解密。因此,您可以加密ID,将其发送到客户端,客户端将其发回,您可以再次解密。无需额外的数据库记录。更安全的是加密/解密用当前客户端的类似IP的记录ID,因此即使是URL钓鱼也会减少问题。
请参阅:http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx
答案 3 :(得分:1)
所有其他答案(3)未能涵盖这是非熟练,未经过身份验证,非会话,未登录用户的可能性。
例如,订单后的确认页面等......
在这种情况下,您的身份验证基于URL中的密码。你使用一个秘密,出于所有实际目的是不可思议的,并且每个记录都非常独特。然后你假设如果用户有这个秘密,那么他们可以访问所述记录等...
真正的挑战是找到制作秘密UUID的好方法。许多开发人员将使用rand()+ time()+ uuid()+ remote_ip()或类似的东西(这通常就足够了)的SHA1(),但我确信这里有很多文档。
是的,在您有未经身份验证的用户访问特定数据或执行操作(例如密码重置)的情况下,您需要在记录中包含第二个标识符(例如,varchar 40)一个独特的键(如您所述)。用非常随机的数据填充,如果他们有这个秘密,那就让他们进去。
小心。
答案 4 :(得分:0)
我想说的是,URL是公开的,它不是机密数据。没有必要隐藏用户的网址。如果一个用户可以看到一个URL并且不应该可以访问另一个用户,则应该从服务器端检查该用户的权限,而不是隐藏该URL。