Php 这是使用$\u GET的合理安全的方式吗

Php 这是使用$\u GET的合理安全的方式吗,php,security,get,Php,Security,Get,我只是一个周末的程序员,只在我自己的项目上工作,但我想以一种合理安全的方式使用$GET。我通常使用$\u GET从一个包含许多项目的表中获取,我想对这些项目执行一些编辑、删除操作。你们这些退伍军人中有没有人看到我创建的函数有任何安全问题,或者用一种更简单更优雅的方法来实现它?谢谢你的意见,谢谢 <?php session_start(); if (empty($_SESSION['SecretKey'])) { $_SESSION['SecretKey'] = bin2hex(op

我只是一个周末的程序员,只在我自己的项目上工作,但我想以一种合理安全的方式使用$GET。我通常使用$\u 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>

Hello there weekend coder,我看到的使用GET方法的唯一问题是用户可以直接更改url中的GET数据。例如,让我们以youtube为例,至少在过去,每个youtube视频都有一个GET值v,它的值是一些随机的64位字母数字十六进制数字散列,您可以直接在URL youtube com/watch?v=xxxxxxxxxxxx中看到它,因为这样,您可以手动更改此值,因为您更改了视频id号,因此它将带您转到另一个视频。这很有用,因为您可以复制此链接并将其发送给朋友

另一方面,POST是不同的,因为您不能真正直接更改发送的POST数据值。虽然也有一些恶作剧的方式,但这就是为什么POST表单和值总是需要表单验证的原因

如果我们将youtube的方法改为使用POST,所有youtube视频都会将youtubeDOTcom作为URL,视频ID将作为POST隐藏在页面下方。现在,用户无法直接看到视频的随机唯一ID,也无法将链接发送给其他人共享


希望这能解释一点,这取决于你发送的信息类型。如果您认为它应该是安全的,并且对所有用户都不可见,请使用POST。如果您希望共享链接并经常更改以查看不同的页面、媒体等,这不是机密信息,您可以使用GET

您想保护什么?与此相反,您应该使用HTTP方法,即POST Create、GET REQUERATE、PUT Update、DELETE,然后GET参数中的CSRF只能GET,将其与安全SQL查询等结合使用,并且对url中的令牌进行编码是没有用的,也不要使用md5使用哈希_hmac之类的东西来对数据进行签名。如果用户必须登录才能删除\编辑,那就检查一下。如果您试图保护猜测的id,只需在数组中添加一个随机哈希就可以完全替换“id”,在这里它不需要是用户唯一的。只需防止用户篡改URL即可。我正在研究POST-Create、GET-Retrieve、PUT-Update和hash_-hmac。谢谢你的信息。除了使用HMAC,还应该考虑在URL中正确地避开所有数据。使用http_构建_查询完成整个任务!使用数据的规范版本,而不仅仅是散列查询字符串本身,否则参数顺序将无法更改。也可以在URL注入HTML的任意数据周围使用htmlspecialchars,以便正确转义。一些恶作剧的方式有些很容易使用浏览器插件测试API,如RestClient,或者使用十几个这样的插件中的任何一个来更改post。我使用相同的插件来测试我用非恶意方式制作的API。是的,先生。甚至直接编辑HTML代码,添加一个新的表单和输入标记,并使用正确的名称值和重定向页面名称。你对它们应该使用的HTTP动词的详细说明,我讨厌人们创建搜索页面和使用POST,这让我发疯。。。Lol用密钥散列$\u GET数据并执行校验和不会防止URL被篡改吗?感谢您的回复。一次散列不是单向的,即使是双向的,客户端和服务器都需要密钥,如果您使用非对称加密公钥和私钥,在Javascript中很难实现这一点。而且公钥很容易获得,因此可以简单地伪造消息。