我读过在URL中使用数据库密钥是一件坏事。在URL中存储数据库密钥的一些技巧是什么
例如,
我的表有3个字段:ID:int
,Title:nvarchar(5)
,Description:Text
我想创建一个显示记录的页面。喜欢的东西...
http://server/viewitem.aspx?id=1234
首先,可能有人阐述为什么这是一个糟糕的事是什么?
其次,有什么方法可以解决在URL中使用主键?
我读过在URL中使用数据库密钥是一件坏事。在URL中存储数据库密钥的一些技巧是什么
例如,
我的表有3个字段:ID:int
,Title:nvarchar(5)
,Description:Text
我想创建一个显示记录的页面。喜欢的东西...
http://server/viewitem.aspx?id=1234
首先,可能有人阐述为什么这是一个糟糕的事是什么?
其次,有什么方法可以解决在URL中使用主键?
我认为在URL中使用主键是完全合理的。
但是有些注意事项:
1)避免SQL注入攻击。如果您只是盲目接受id URL参数的值并将其传递到数据库中,则存在风险。确保您清理输入,以便它匹配您拥有的任何格式的密钥(例如,去除任何非数字字符)。
2)SEO。如果您的网址包含关于该项目的某些上下文(例如“大蓬松兔子”而非1234),则会有所帮助。这有助于搜索引擎看到您的网页是相关的。它也可以用于你的用户(我可以从我的浏览器历史记录中知道哪个记录是哪个记录而不必记住一个数字)。
有时候这有些迂腐,但是您希望为事物使用唯一的商业标识符而不是代理键。
它可以像ItemNumber而不是Id一样简单。
该Id是一个数据库问题,而不是业务/用户关心的问题。
这并不是一件坏事,但它有一些注意事项。
请注意,有人可以输入不同的密钥,也许可以提取您不希望/希望他们获得的数据。你可以通过增加你的密钥空间来降低这个成功的可能性(例如让id为随机的64位数)。
注意二,如果你正在运行一项公共服务,并且你有竞争对手,他们可能能够从你的密钥中提取商业信息,如果它们是单调的。示例:今天创建帖子,在一周内创建帖子,比较ID和您提取帖子的速率。
注意三是它很容易发生SQL注入攻击。但是你永远不会犯这些错误,对吧?
默默无闻的安全措施无效。如果您担心用户可能通过访问某个url访问敏感数据,则需要为数据添加实际保护 - 需要授权,并验证授权用户是否有权查看给定资源。 – Aeon 2008-09-17 00:59:48
2a。使用适当的授权。 2b。主键使用GUID。
显示密钥本身并不是固有的不好,因为它没有真正的意义,但是显示获得对某个项目的访问方式是不好的。
例如说你有一个网上商店卖2个商家的东西。商人A有物品(1,3,5,7),商人B有物品(2,4,5,8)。
如果我逛街的商人A的网站,看看: http://server/viewitem.aspx?id=1
我可能会尝试与它类型拨弄: http://server/viewitem.aspx?id=2
这可能让我进入一个项目,我不应该因为我正在与Merchant A而不是B购物。一般来说,允许用户摆弄这样的东西会导致安全问题。另一个简短的例子是员工可以查看他们的个人信息(ID = 382),但他们键入其他人的ID直接转到其他人的个人资料。
现在,只要说安全检查是建立在系统内部的检查,以确保人们正在做他们应该做的事(例如:不与其他商人一起购物或不看另一个商家雇员)。
一种机制是在会话中存储信息,但有些不喜欢这样。我不是一个网络程序员,所以我不会去进入:)
最重要的是要确保系统是安全的。永远不要相信用户回来的数据。
在URL中使用ID不一定是错误的。这个网站使用它,尽管是由专业人士完成的。
他们怎么会危险?当允许用户更新或删除属于他们的条目时,开发人员实施某种认证,但他们经常忘记来检查输入是否真的对你来说是。当恶意用户注意到“12345”属于你时,它可能会形成一个类似于"https://stackoverflow.com/questions/12345/delete"
的URL,并将其删除。
程序员应该确保在执行此类操作之前,具有任意ID的数据库条目确实属于当前登录的用户。
有时有很多原因可以避免在URL中暴露ID。在这种情况下,开发人员通常会为其每个条目生成随机哈希值并将其用于URL中。在URL栏中篡改的恶意人员很难猜测属于某个其他用户的散列。
安全和隐私是避免这样做的主要原因。任何提供数据结构的信息都是黑客可以用来访问数据库的更多信息。正如mopoke所说,你也暴露在SQL注入攻击中,这些攻击相当普遍,并且可能会对你的数据库和应用程序造成极大的伤害。从隐私的角度来看,如果您显示任何敏感或个人信息,任何人都可以用数字替代检索信息,如果您没有认证机制,则可能会使您的信息处于危险之中。另外,如果查询数据库很容易,那么只要有人通过URL对服务器进行循环,就会让自己面临拒绝服务攻击,因为他们知道每个人都会得到响应。
无论数据的性质如何,我倾向于建议不要在URL中分享任何可能会泄露应用程序体系结构的任何内容,在我看来,您只是在招惹麻烦(我对隐藏域感到相同这些并不真正隐藏)。
为了解决这个问题,我们在通过参数之前先对参数进行加密。在某些情况下,加密的URL还包含某种形式的验证/验证机制,因此服务器可以决定是否可以处理。
当然,每个应用程序都是不同的,您要实现的安全级别必须与功能,预算,性能等进行平衡。但是在数据安全性方面,我并没有看到任何错误。
大家似乎都在使用这种技术发布“问题”,但我还没有看到任何解决方案。有什么选择。 URL中必须有一些内容可唯一定义要显示给用户的内容。我能想到的唯一的其他解决方案是将整个网站从表单中运行,并让浏览器将值发布到服务器。因为所有链接都需要表单提交,所以编码有点麻烦。而且,对于网站用户来说,只需要付出他们希望的任何价值的最低难度。此外,这不会允许用户收藏任何内容,这是主要的缺点。
@John Virgolino提到加密整个查询字符串,这可能有助于此过程。然而,对于大多数应用程序来说似乎有点过分。
我一直在阅读这方面的内容,寻找解决方案,但是@ Kibbee说没有真正的共识。
我能想到的几个可能的解决方案:
1)如果您的表使用整数键(有可能),加上一个校验和数字来标识。这样,(简单)注入攻击通常会失败。在收到请求后,只需删除检查和数字,并检查它是否仍然匹配 - 如果他们不知道URL是否被篡改。这种方法也隐藏了你的“增长率”(略)。
2)当最初存储数据库记录时,保存一个“辅助键”或值,你很乐意成为一个公共ID。这必须是唯一的并且通常不是顺序的 - 例子是UUID/Guid或整数ID的散列(MD5),例如http://server/item.aspx?id=AbD3sTGgxkjero(但要小心与http不兼容的字符)。铌。辅助字段需要被编入索引,并且您将失去1)中获得的集群的好处。
2)不是真的。这是一个都市传奇。我有几个网站,我试着用和不用,页面得到完全相同的PR,无论它们是标题为1.php还是eat_the_dinner.php。没有任何效果。重要的是标题,页面上的第一个H1标签和其他链接。 – 2008-09-17 03:11:01
这个回复虽然被接受,但并未涵盖安全方面。显而易见的是;您必须确保查看此人的人有权查看此人;但是做得稍微少一点,那就是你应该注意,对于你使用顺序编号的人来说这是显而易见的。这可能是不好的,这取决于你是什么,以及你显示多少。 – 2009-10-06 09:40:10