【发布时间】:2018-09-14 00:50:42
【问题描述】:
我只是一个周末编码员,只从事我自己的项目,但我想以一种相当安全的方式使用 $_GET。我通常使用表中的 $_GET ,其中包含许多我想对其执行某些操作(编辑、删除)的项目。你们中的任何一位退伍军人是否看到我创建的功能或更简单更优雅的方法存在任何安全问题?感谢您的任何意见,谢谢。
<?php session_start();
if (empty($_SESSION['SecretKey'])) {
$_SESSION['SecretKey'] = bin2hex(openssl_random_pseudo_bytes(16));
}
function GetURLEncode($ArrayData,$SecretKey,$Echo = true) {
$GetQuery = http_build_query($ArrayData,'','&');
$Checksum = http_build_query(Array("Checksum" => hash_hmac('ripemd160', $GetQuery, $SecretKey)));
if ($Echo) {
echo '<a href="?'.$GetQuery.'&'.$Checksum.'">'.htmlspecialchars($ArrayData['Action']).'</a>';
} else {
return "?".$GetQuery."&".$Checksum;
}
}
function GetURLDecode($GetData,$SecretKey,&$ReturnData) {
$Checksum = $GetData['Checksum'];
unset($GetData['Checksum']);
$GetQuery = http_build_query($GetData,'','&');
if (hash_equals(hash_hmac('ripemd160', $GetQuery, $SecretKey),$Checksum)) {
$ReturnData = $GetData;
return true;
}
$ReturnData = "";
return false;
}
if (!empty($_GET)) {
if (GetURLDecode($_GET,$_SESSION['SecretKey'],$ReturnData)) {
echo "Array Returned<br>";
echo var_dump($ReturnData)."<br><Br>";
} else {
echo "Checksum Error<br><br>";
}
}
//Example 1
$MyArray1 = Array ("FirstName" => "John",
"LastName" => "Doe",
"Adderss" => "12345 MyStreet",
"City" => "Apple Valley",
"State" => "California");
echo "Sample 1<br>";
$URL = GetURLEncode($MyArray1,$_SESSION['SecretKey'],false);
echo '<a href="'.$URL.'">Click Me</a>';
//Example 2
$MyArray2 = Array(Array("Id" => 0,"Make" => "Chevy","Model" => "HHR"),
Array("Id" => 1,"Make" => "Chevy","Model" => "Corvette"),
Array("Id" => 2,"Make" => "Ford","Model" => "Mustang"),
Array("Id" => 3,"Make" => "Nissan","Model" => "Sentra"),
Array("Id" => 4,"Make" => "Ford","Model" => "Ranger"),
Array("Id" => 5,"Make" => "Dodge","Model" => "Charger"));?>
<br><br>
<table>
<th>sample 2</th>
<?php foreach ($MyArray2 as $Array) { ?>
<tr>
<td><?= $Array['Make'];?></td>
<td><?= $Array['Model'];?></td>
<td><?php GetURLEncode(array("Id"=>$Array['Id'],"Action"=>"Edit"),$_SESSION['SecretKey']);?></td>
<td><?php GetURLEncode(array("Id"=>$Array['Id'],"Action"=>"Delete"),$_SESSION['SecretKey']);?></td>
</tr>
<?php } ?>
</table>
【问题讨论】:
-
你想保护什么?取而代之的是,您应该使用 HTTP 方法,即 POST(创建)、GET(检索)、PUT(更新)、DELETE,然后 GET 参数中的 CSRF 只能 GET,将其与安全 SQL 查询等结合起来,没有用在对 url 中的令牌进行编码时,也不要使用 md5 使用 hash_hmac 之类的东西,它用于签名数据。
-
如果用户必须登录才能删除\编辑,那么只需检查一下即可。如果您试图保护猜测的 id,只需向数组中添加一个随机哈希(可以完全替换“Id”),这里不需要用户唯一。
-
只是试图防止用户篡改 URL。我正在研究 POST(创建)、GET(检索)、PUT(更新)和 hash_hmac。感谢您的信息。
-
除了使用 HMAC 之外,还应考虑正确转义 URL 中的所有数据。 (对整个事情使用
http_build_query()!使用数据的规范版本,而不仅仅是对查询字符串本身进行哈希处理,否则参数顺序将无法更改。)还可以在任意数据周围使用htmlspecialchars()(您的URL ) 注入 HTML 以便正确转义。