防止用户操纵查询字符串参数


Prevent user from manipulating query string parameter

情况:未注册用户访问网站并发出项目请求。根据当前的数据流,这个请求首先被插入到db中,请求id在后续页面的url中被传递(用户可以在其中添加进一步的信息)。

问题:用户可以更改id。

我到目前为止所做的:一旦我通过使用lastInsertId()插入请求后检索id,我将其存储在会话变量中,并根据$_GET中的id检查后续页面。我还实现了CRSF保护,但是当令牌匹配时,会话令牌不设置。因此,即使用户在相同的url上刷新,检查也会失败。

如何解决这个问题?请指出我缺乏的概念。另外,当许多并发用户发出请求时,服务器会根据其唯一会话id确定哪个用户的id不同用户的id不同,对吧?这种并发性是否会导致任何问题或漏洞?

基于行'(用户得到添加在进一步的信息)'我假设你正在使用某种形式/POST来获取数据?我会使用atulbhat评论中所述的技术,并在中使用散列数据。您可以在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');
}

因为'salt' (aRandomSaltStringOnlyKnownByYourScript)只在你的脚本中知道,这是非常非常难以解码和改变与哈希值匹配的手动更改ID的get。

很明显,就像所有的通道一样,盐越浓,裂缝越硬。因此,加入一些空格、数字或甚至其他字符来抓住坏人。

理想情况下,您应该避免保留应该在url中可见的秘密数据,因此我建议您应用Pim的解决方案,但将散列值存储在cookie中,而不是传统用户比url参数更难以访问的cookie。