防止查询字符串被篡改

时间:2016-07-12 06:16:49

标签: php query-string

我编写了一个脚本,我需要将url中的用户信息作为查询字符串传递给下一页但是如果我改变传递的参数,那么与该页面相关的实际数据也会发生变化,以防止如何防止对查询字符串的更改/篡改。我通常不使用查询字符串,所以我真的不知道防止它们被篡改的最佳方法。

用法#1:

<button class="btn btn-blue btn-xs">
    <i class="fa fa-comments"></i>
    <a href="comment.php?u_id='.$row['id'].'&v_no='.$row['vault_no'].'"> Comment</a>
</button>

用法#2:

<form id="form" name="form" method="GET" class="m-t" role="form" action="profile_1.php" autocomplete="off">
    <!--Field parameters-->
    <input style="vertical-align: middle" type="submit" name = "receive" id="submit" value="Post"  class="button">

这是我处理查询的方式:

if (isset($_GET['Receive'])) {      
    //receiving get parameters
    $xyz = $_GET['xyz'];
    $abc = $_GET['abc'];

3 个答案:

答案 0 :(得分:2)

您无法阻止用户进行篡改,无论是$_GET查询篡改还是基于cURL的查询,这只是它的方式,但是你可以让它变得更难用户使用加密或令牌篡改。假设您有任何类型的用户输入,它可能会被篡改。 快速说明,我不是任何想象力的密码学专家,所以不要把它作为经典。您应该根据需要进行更多研究。如果您需要保留已登录用户的数据,您应该考虑使用会话而不是通过$_GET查询传递。

双向数据加密:

根据您的需要,openssl可能是一种选择。如果我想传输数据但我不想让最终用户以明文看到,我会使用这种类型的东西。我永远不会在客户端传输敏感数据,但如果你想阻止你的用户搞乱,这个函数库可能会有用。

正确实施openssl_encrypt()会给你一个类似于:

的字符串
nGaotAznsYN69aU%2BNun90vguvhQzk8KW%2BI2RZoom28YqKr05HTeSwPYbMgnPlepj

因此,在查询字符串中,它看起来像:

<a href="http://www.example.com/?val=nGaotAznsYN69aU%2BNun90vguvhQzk8KW%2BI2RZoom28YqKr05HTeSwPYbMgnPlepj">CLICK</a>

使用此方法,如果解密失败openssl_decrypt()(因为篡改已破坏字符串),解码应返回empty,因此您只需考虑empty

// $dec would be the decrypted data from $_GET['val']
if(empty($dec))
    die('Invalid data.');

NONCE / TOKEN(S):

如果是您要保护的操作(您希望确保只有某个用户或组可以在您的应用中运行某个操作),您可以尝试存储并检查nonce。 WordPress是一个使用nonce的应用程序。

如果您要保留数据本身,则可能需要使用一对随机生成的令牌进行两点身份验证,其中将一对保存到具有实际值的数据库中存储在同一行,因此在进行查询时,您可以匹配两个标记并返回实际数据(或操作字以允许程序相应地做出反应):

<a href="http://www.example.com/?key=213Adfa316&token=9821745uwnwoi62626novVBei1qu4p">CLICK</a>

<!--
// the key and token would be in the database along with the corresponding data or action to take,
// you would have to figure that out...
// Then you would just use a select statement to get the data back:
// OF COURSE YOU WOULD BIND VALUES HERE!!!
-->

$smt = "SELECT `savedData` FROM `action_table` where `rKey`='213Adfa316' AND `rToken`='9821745uwnwoi62626novVBei1qu4p'"

注意:有很多不同的方法可以做同样的事情但是如果你使用的是框架,那么可能有一种原生于该框架的方法。我会对其他方法做更多的研究,但希望这有助于给你一些想法。正如 @zaph 所述,正确实施加密非常重要。如果安全性是目标, @zaph 也会注意到,使用https将是保护客户端/服务器通信的方法。另外要记住的一点是,浏览器可以将查询字符串存储为URL历史记录或服务器的一部分,作为日志的一部分,因此如果您需要一次性使用URL,则需要适应该重用政策。

答案 1 :(得分:0)

对此的简短回答是,如果信息非常敏感,不发送给任何人。保持本地化。您可以发送对此信息的引用,将其用作令牌以在以后的请求中检索它。

例如,生成UUID,将包含敏感信息的文档保存在某个本地数据存储中,并在URL中链接UUID。可能从UUID中收集的信息并不是很多,至少没有一个与秘密商店内部的信息有关。

Redis这样的短期数据存储对于这种持久性非常方便。您可以在数据上设置TTL,以便将来某个时间点自动清除。到期时间为24-48小时应该足够了,如果您需要在每次使用时都延长此期限。

真正随机的UUID将无法猜测。任何试图暴力破解的人都应该被服务器上的限速机制捕获,如果这是一个问题。

答案 2 :(得分:-1)

嗨您可以使用第一种方法。以下是您的解决方案

<强> 1。如果没有使用php Tag

<a href="comment.php?u_id=<?php echo $row['id']; ?>&v_no=<?php echo $row['vault_no']; ?>">Click Here</a>

<强> 2。如果在Php标签中使用

<?php 
echo "<a href='comment.php?u_id=".$row['id']."&v_no=".$row['vault_no']."'>Check Here2</a>"
?>