我已经读过在URL中使用数据库密钥是一件坏事。
例如,
我的表格包含3个字段:ID:int
,Title:nvarchar(5)
,Description:Text
我想创建一个显示记录的页面。有点像...
http://server/viewitem.aspx?id=1234
首先,有人可以详细说明为什么这是一件坏事吗?
其次,有哪些方法可以解决在网址中使用主键的问题?
答案 0 :(得分:4)
我认为在网址中使用主键是完全合理的。
但有些注意事项:
1)避免SQL注入攻击。如果您只是盲目地接受id URL参数的值并将其传递给DB,那么您将面临风险。确保您对输入进行清理,使其与您拥有的任何格式的键匹配(例如,删除任何非数字字符)。
2)SEO。如果您的网址包含有关该项目的某些上下文(例如“大蓬松兔子”而不是1234),这会有所帮助。这有助于搜索引擎看到您的网页是相关的。它对你的用户也很有用(我可以从我的浏览器历史记录中看出哪条记录不需要记住一个数字)。
答案 1 :(得分:2)
这本身并不是一件坏事,但它有一些警告。
值得注意的是,有人可以输入不同的密钥,也可能会提取您不希望/希望他们获取的数据。您可以通过增加密钥空间来减少成功的可能性(例如,使id为随机的64位数字)。警告二,如果您正在运行公共服务并且您有竞争对手,那么如果他们是单调的,他们可能能够从您的密钥中提取业务信息。示例:今天创建一个帖子,在一周内创建一个帖子,比较ID并且你已经提取了帖子的评分率。
警告三,它容易发生SQL注入攻击。但你永远不会犯那些错误,对吗?答案 2 :(得分:1)
在URL中使用ID并不一定是坏事。该网站使用它,尽管由专业人士完成。
他们怎么会有危险?当允许用户更新或删除属于他们的条目时,开发人员会实施某种身份验证,但他们经常忘记来检查条目是否真的属于。恶意用户在注意到“12345”属于您时会形成"/questions/12345/delete"
之类的网址,并且会被删除。
在执行此类操作之前,程序员应确保具有任意ID的数据库条目确实属于当前登录用户。
有时候有充分的理由避免在网址中公开ID。在这种情况下,开发人员通常会为每个条目生成随机哈希并使用URL。篡改URL栏的恶意人员很难猜测属于其他用户的哈希值。
答案 3 :(得分:1)
安全和隐私是避免这样做的主要原因。任何泄露数据结构的信息都是黑客可用于访问数据库的更多信息。正如mopoke所说,你也暴露于SQL注入攻击,这种攻击相当普遍,对你的数据库和应用程序非常有害。从隐私的角度来看,如果您显示任何敏感或个人信息,任何人都可以用一个数字替换来检索信息,如果您没有身份验证机制,您可能会将您的信息置于风险之中。此外,如果您可以轻松查询数据库,那么您可以通过URL对服务器进行循环访问来打开拒绝服务攻击,因为他们知道每个人都会得到响应。
无论数据的性质如何,我倾向于建议不要在URL中共享可能会泄露任何有关应用程序架构的任何内容,在我看来,你只是在招惹麻烦(我对隐藏的字段有同样的看法)不是真的隐藏了。)
为了解决这个问题,我们会在传递参数之前对其进行加密。在某些情况下,encyrpted URL还包括某种形式的验证/身份验证机制,因此服务器可以决定是否可以处理。
当然,每个应用程序都是不同的,您要实现的安全级别必须与功能,预算,性能等进行平衡。但在数据安全方面,我没有看到任何偏执的错误。< / p>
答案 4 :(得分:0)
有时候这有点迂腐,但是你想要为事物使用唯一的商业标识符而不是代理键。
它可以像ItemNumber一样简单,而不是Id。
ID是数据库关注点,而非业务/用户关注点。
答案 5 :(得分:0)
2a上。使用适当的授权。 2B。使用GUID作为主键。
答案 6 :(得分:0)
显示密钥本身并不是坏事,因为它没有任何实际意义,但显示获取对项目的访问权限的方法很糟糕。
例如,假设您有一家网上商店,可以从2家商家那里购买商品。商家A有物品(1,3,5,7),商人B有物品(2,4,5,8)。如果我在Merchant A的网站上购物,请看: http://server/viewitem.aspx?id=1
然后我可以尝试摆弄它并键入: http://server/viewitem.aspx?id=2
这可能让我访问一个我不应该访问的项目,因为我正在使用商家A而非B购物。通常允许用户摆弄这样的东西会导致安全问题。另一个简短的例子是员工,他们可以查看他们的个人信息(id = 382),但他们输入其他人ID直接转到其他人的个人资料。
现在,已经说过......只要在系统中内置安全检查以确保人们正在做他们应该做的事情(例如:不与其他商家一起购物或不查看其他员工),这也不错)。
一种机制是在会话中存储信息,但有些机制不喜欢这样。我不是网络程序员所以我不会进入那个:)
主要是确保系统安全。永远不要相信从用户那里回来的数据。
答案 7 :(得分:0)
每个人似乎都在使用这种技术发布“问题”,但我还没有看到任何解决方案。有什么选择。 URL中必须有一些内容,用于唯一定义要向用户显示的内容。我能想到的唯一其他解决方案是从表单中运行整个站点,并让浏览器将值发布到服务器。这对代码来说有点棘手,因为所有链接都需要提交。此外,对于网站用户来说,放入他们想要的任何价值的难度最小。此外,这也不允许用户为任何内容添加书签,这是一个主要的缺点。
@John Virgolino提到加密整个查询字符串,这可能有助于这个过程。然而,对于大多数应用程序来说似乎有点太过分了。
答案 8 :(得分:0)
我一直在读这个,寻找解决方案,但正如@Kibbee所说没有真正的共识。
我可以想到一些可能的解决方案:
1)如果您的表使用整数键(可能),请在标识符中添加校验和数字。这样,(简单)注入攻击通常会失败。收到请求后,只需删除校验和数字并检查它是否仍然匹配 - 如果没有,则表示您已知道URL已被篡改。这种方法也隐藏了你的“增长率”(某种程度上)。
2)最初存储数据库记录时,请保存您很乐意成为公共ID的“辅助密钥”或值。这必须是唯一的并且通常不是顺序的 - 示例是整数ID的UUID / Guid或散列(MD5),例如, http://server/item.aspx?id=AbD3sTGgxkjero(但要注意与http不兼容的字符)。铌。辅助字段需要编入索引,您将失去1)中的聚类优势。