我希望允许用户通过关注URL查看我的数据库中的记录。
我猜这个URL不是一个好主意,其中要查看的记录的标识符是记录自动增量ID!
http://www.example.com/$db_record_id
以上是不必要地提供信息。这是真的吗?不会为每一行创建自己的ID会造成同样的问题吗?
有没有更好的方法来解决我的问题。
环境:LAMP(PHP)
全部谢谢
答案 0 :(得分:3)
您要发出两条信息:
这些事情对您的应用程序是一个问题,然后使用其他东西
您可以将GUID用于Db密钥,但这可能会对大型数据集产生潜在的性能影响。
答案 1 :(得分:3)
将记录的ID放在URL中通常不是问题。例如,查看此浏览器窗口的URL,您将看到此问题的ID。
如果由于某种原因不希望ID清晰可见,您可以对值进行加密或加密。如果您需要保护某些记录不被查看,这当然不是一种安全的方法,那么您必须将其与某种身份验证相结合,例如登录用户的会话ID。
编辑:
为了保证适当的安全性,必须关注真正的问题。如果某些页面应该限制访问,问题不是任何人都可以找到页面的URL,问题是任何人都可以查看该页面。 URL总是可以通过某种方式获得(例如包嗅探),因此必须以其他方式实现安全性。
答案 2 :(得分:2)
您提供的信息太少,无法提供真正有用的答案。
那就是说,我同意公开这样的ID是有问题的。 commmon解决方案是每次向数据库查询一组记录时生成临时ID,并在内部存储tempID->真实ID。然后将这些临时ID放入URL中,并在服务器上进行翻译。
答案 3 :(得分:2)
该方法的一个可能问题是,通过顺序递增URL中的ID,人们很容易检索所有页面/记录。这可能不是您想要的,但是您不应该依赖于使用模糊的URL来保证安全。
其他一些选择是:
答案 4 :(得分:2)
如果我是你,我会在你的桌子上使用整数主键(自动识别码)
并添加一个具有唯一约束的GUID&索引,默认为UUID()
然后装备您的页面以获取URL上的GUID并使用它来搜索您的表。
答案 5 :(得分:1)
也许您应该公开另一个唯一标识符,例如标题而不是主键?公开您的PK不一定会带来安全风险,但如果您可以公开其他属性,您可能会在搜索结果上获得更高的优势。
答案 6 :(得分:1)
用户请求中的主键本身不容易受到攻击。只需将其转换为整数值即可。
$id = (int)$id;
。
另一个问题是限制某些记录的访问。您可以通过简单编辑查询来解决此问题,并添加一些访问规则。例如,如果您有admin / editor / reader / guest类型的用户,则可以在SET字段中保存访问权限并将条件添加到查询中
SELECT ...
FROM mytable
WHERE
id = (int)$id
AND
(FIND_IN_SET('admin', access) OR FIND_IN_SET('editor', access))
...
if (!$fetch = mysql_fetch_acssoc($res))
throw new Exception('Record not found or you have no permission to access it');
所以,不要担心主键 - 如果你不忘记将它们转换为整数以避免SQL注入,它们是非常安全的。
答案 7 :(得分:0)
这不是一个好主意,因为它已经被说过了(你实际上暴露了表中的每一行),我认为没有必要。
我认为用户将在某个场景(从列表中选择元素或其他内容)后到达该页面,因此您将有一个页面提交和一个控制器(如果您尝试使用MVC架构)将处理所需的任何处理,它将发送到一个查看页面,该页面可能只是一个www.yoursite.com/displayElement.htm
通过这种方式,ID只是作为会话变量传递,不会显示在任何地方。
但是如果我弄错了并且你正在显示某种目录,那么你希望用户能够为页面添加书签,而不是只需要添加一些混淆机制来创建基于ID的复杂字符串,在将ID发送到URL并在代码中解码之前对ID进行编码以获得实际ID。
答案 8 :(得分:0)
如果用户无论如何都可以观看该页面,我发现使用该ID没有问题。如果他们想要改变网址并转到随机页面,我会毫无疑问。
如果不让任何人看到这些页面,我实际上仍然没有问题。因为如果是这种情况,你应该进行一些授权检查,这会阻止他们看到他们不被允许看到的页面。
答案 9 :(得分:0)
您所描述的是称为直接对象引用的漏洞。这些本质上并不是坏事,但是Insecure Direct Object References在OWASP前十名中是#4。
您可以通过检查属于当前用户的对象来保护直接对象引用,如果不存在则不显示它。
此外,即使是拒绝访问的消息也可能会泄露信息。例如,如果您的参数是一个订单号,攻击者可以发现您的公司实际拥有的订单数量,即使您没有显示它们只需增加数量直到获得404。
我个人只是使用GUID作为间接对象引用的一种形式,但显然不是数据库中的主键。
答案 10 :(得分:0)
威胁级别取决于范围和受众:
一般来说,我赞成可预测的URL。话虽如此,重要的是要考虑如何使用它们以及谁可以看到它们。
答案 11 :(得分:0)
如果你想确保人们不只是猜测URL,那么这是一个简单的方法。这绝不是安全(即不要使用此方法进行访问检查),但它将确保您不能只输入随机URL并将sendt发送到该页面。< / p>
使用网址中的另一条信息补充ID。我建议使用id的盐渍哈希。
生成网址时:
$id = 5;
$hash = md5($id . "MY_SALT_VALUE");
$url = "/$id/$hash";
显示记录时:
$params = explode(',', $_SERVER['REQUEST_URL']);
$id = $params[0];
$hash = $params[1];
if($hash != md5($id ."MY_SALT_VALUE")) {
die('Uh oh! You guessed the URL, didn\'t you! Bad user!');
}
$data = $MyModel->load($id);
if(!$data) {
die('No such record');
}
DisplayModel($data);
当然,这是一个模型(在错误消息中说太多,只是die()
而不是正确的404页面,依此类推。)