【问题标题】:Is this a reasonably secure way to use $_GET这是使用 $_GET 的合理安全方式吗
【发布时间】: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 以便正确转义。

标签: php security get


【解决方案1】:

周末编码员你好,我看到使用 GET 方法的唯一问题是用户可以直接更改 url 中的 GET 数据。例如,让我们以 youtube 为例(至少在过去),每个 youtube 视频都有一个 GET 值v,它的值是一些随机的 64 位字母数字十六进制哈希,你可以直接在 URL @ 中看到它987654322@ 既然是这样,您可以手动更改此值,因为您更改了video id number,它会将您带到另一个视频。这很有用,因为您可以复制此链接并将其发送给您的朋友。

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

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

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

【讨论】:

  • some mischievous ways some 它很容易使用浏览器插件来测试 API,例如 RestClient,或十几个这样的插件中的任何一个来更改帖子。我使用相同的插件来测试我以非恶作剧方式制作的 API。
  • 是的,先生。甚至直接编辑 HTML 代码并添加具有正确名称值和重定向页面名称的新表单和输入标签。
  • 你对一个应该使用什么 Verbage(它们是 HTTP 动词)的标记,我讨厌人们制作搜索页面并使用 POST 它只会让我发疯......哈哈
  • 不会使用密钥散列 $_GET 数据并执行校验和以防止 URL 被篡改吗?感谢您的回复。
  • No for one 哈希是一种方式,即使是2方式,客户端和服务器都需要密钥,如果使用非对称加密(公钥私钥),那就很难了在Javascript中实现它。而且公钥很容易获得,因此可以简单地伪造一条消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-02
  • 2010-11-08
相关资源
最近更新 更多