情况:未注册的用户访问网站并发出项目请求。根据当前数据流,此请求首先插入到db中,并且请求ID将在后续页面的url中继承(用户可以在其中添加更多信息)。
问题:用户可以更改ID。
到目前为止我做了什么:一旦我使用lastInsertId()插入请求后检索id,我将它存储在会话变量中并检查后续页面中的id来自$ _GET。我还实现了CRSF保护,但是当令牌匹配时,会话令牌被取消设置。因此,即使用户刷新同一个URL,检查也会失败。
我如何解决这个问题?请指出我缺乏的概念。此外,当许多并发用户发出请求时,服务器会根据不同用户的唯一会话ID来确定哪个用户属于哪个用户,这是正确的吗?由于这种并发性,是否会出现任何问题或漏洞?
答案 0 :(得分:3)
基于该行'(用户可以在其中添加更多信息)'我假设您正在使用某种形式/ POST来获取数据? 我将使用AtulBhatS注释中所述的技术并使用散列数据。您可以在GET中设置散列数据,也可以将其设置在前面提到的表单/ POST字段中的隐藏字段中。
基本上它是这样的:
$id = $thisRequestIdOfYours;
$hash = hash('sha512', 'aRandomSaltStringOnlyKnownByYourScript'.$id);
只需将这两个值用作$ _GET(而不是像现在这样只使用$ id)。或者将其设置在隐藏的字段中。
重新发布帖子后,您可以进行检查:
// Use $_POST if you use the hidden field way.
if( hash(sha512, 'aRandomSaltStringOnlyKnownByYourScript'.$_GET['id']) !== $_GET['superSecretHash']) {
// h4x0r d3tect3d
die('you have no business here');
}
因为盐和# (aRandomSaltStringOnlyKnownByYourScript)只在您的脚本中已知,使用散列解码和更改get以使其与手动更改的ID匹配非常困难。
显然与所有通行证一样,盐越强,裂缝就越难。所以扔一些空格,数字,甚至其他字符来捕捉坏人。
答案 1 :(得分:0)
理想情况下,您应该避免在网址中保留应该保密的数据,因此我建议您应用Pim的解决方案,但将散列值存储在Cookie中,而不是经典用户可访问的数据库,而不是网址参数。