ホームページ  >  記事  >  バックエンド開発  >  PHP でのクロスサイト リクエスト フォージェリ エラーをトラブルシューティングするにはどうすればよいですか?

PHP でのクロスサイト リクエスト フォージェリ エラーをトラブルシューティングするにはどうすればよいですか?

王林
王林オリジナル
2023-12-17 08:38:311169ブラウズ

PHP でのクロスサイト リクエスト フォージェリ エラーをトラブルシューティングするにはどうすればよいですか?

クロスサイト リクエスト フォージェリ (CSRF) 攻撃はネットワーク攻撃の一般的な手段であり、PHP のアプリケーションでも例外ではありません。ユーザーのログイン状態を利用して攻撃を実行し、正規のユーザーになりすましてリクエストを作成して悪意のあるリクエストを送信し、被害を及ぼします。この記事では、PHP アプリケーションの CSRF 脆弱性を排除する方法を、具体的なコード例と詳細な分析を含めて紹介します。

  1. CSRF トークンの追加

CSRF 攻撃は、リクエストを偽造することで Web サイトの保護メカニズムをバイパスします。一般的なバイパス方法は「パスワード」攻撃です。この攻撃を防ぐには、Web サイトのフォームに CSRF トークンを追加する必要があります。

バックエンド コード:

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
    session_start();
    if($_POST['csrf_token'] == $_SESSION['csrf_token']){
        //请求数据合法,执行操作
    }else{
        //CSRF令牌不合法
    }
}
?>

フロントエンド コード:

<form method="POST" action="submit.php">
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
    <!-- 其他表单数据 -->
    <button type="submit">提交</button>
</form>
  1. 操作ごとに異なる CSRF トークンを使用する

For さらに改善するにはセキュリティの観点から、異なる操作には異なる CSRF トークンを使用する必要があります。

バックエンド コード:

<?php
//生成新的CSRF令牌
function generate_csrf_token(){
    return md5(mt_rand(1, 1000000) . microtime());
}
//验证CSRF令牌
function validate_csrf_token($token){
    if(!isset($_SESSION['csrf_token']) || $_SESSION['csrf_token'] !== $token){
        die("CSRF Token验证失败");
    }
}
//生成CSRF令牌
if(!isset($_SESSION['csrf_token'])){
    //不存在令牌,生成新的令牌
    $_SESSION['csrf_token'] = generate_csrf_token();
}
//用户提交的数据需要先进行CSRF令牌验证
if($_SERVER['REQUEST_METHOD'] == 'POST'){
    validate_csrf_token($_POST['csrf_token']);
    //请求数据合法,执行操作
}
?>

フロントエンド コード:

<form method="POST" action="submit.php">
    <input type="hidden" name="csrf_token" value="<?php echo generate_csrf_token(); ?>">
    <input type="hidden" name="action" value="delete">
    <input type="hidden" name="id" value="123">
    <button type="submit">删除用户</button>
</form>
  1. IP アドレスとユーザー エージェント情報のバインド

CSRF攻撃の目的は、Web サイトのセキュリティ検証をバイパスすることであり、主な予防策は、フォーム送信プロセス中に検証メカニズムを追加することです。セキュリティをさらに強化するために、CSRF トークンをユーザーにバインドできます。

バックエンド コード:

<?php
//生成新的CSRF令牌
function generate_csrf_token(){
    return md5(mt_rand(1, 1000000) . microtime());
}
//验证CSRF令牌
function validate_csrf_token($token){
    if(!isset($_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']])
        || !in_array($_SERVER['HTTP_USER_AGENT'], $_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']])){
        die("CSRF Token验证失败");
    }
    if(!isset($_SESSION['csrf_tokens'][$token])){
        die("CSRF Token验证失败");
    }else{
        unset($_SESSION['csrf_tokens'][$token]);
    }
}
//生成CSRF令牌
if(!isset($_SESSION['csrf_tokens'])){
    $_SESSION['csrf_tokens'] = [];
}
if(!isset($_SESSION['csrf_ips'])){
    $_SESSION['csrf_ips'] = [];
}
if(!isset($_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']])){
    $_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']] = [$_SERVER['HTTP_USER_AGENT']];
}else{
    $_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']][] = $_SERVER['HTTP_USER_AGENT'];
    //限制用户代理
    if(count($_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']]) > 3){
        array_shift($_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']]);
    }
}
$new_token = generate_csrf_token();
$_SESSION['csrf_tokens'][$new_token] = true;
?>

フロントエンド コード:

<form method="POST" action="submit.php">
    <input type="hidden" name="csrf_token" value="<?php echo $new_token; ?>">
    <input type="hidden" name="action" value="delete">
    <input type="hidden" name="id" value="123">
    <button type="submit">删除用户</button>
</form>

上記の方法により、PHP アプリケーションの CSRF 脆弱性を効果的に排除できます。ただし、これらの方法は絶対に信頼できるものではなく、実際の状況に基づいて調整および改善する必要があることに注意してください。同時に、新たなセキュリティ リスクの導入を避けるために、CSRF トークンを URL または Cookie に渡さないようにする必要があります。

以上がPHP でのクロスサイト リクエスト フォージェリ エラーをトラブルシューティングするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。