この記事の例では、繰り返し送信を防ぐために PHP フォームにトークンを追加する方法を説明します。ご参考までに、詳細は以下の通りです:
トークンについて簡単に説明します
トークンはトークンであり、その最大の特徴はランダム性と予測不可能性です。通常のハッカーやソフトウェアはそれを推測できません。
それでは、トークンの機能は何ですか?原理は何ですか?
トークンは一般に 2 つの場所で使用されます - フォームの繰り返し送信と反 csrf 攻撃 (クロスサイト リクエスト フォージェリ) を防ぐためです。
どちらも原則としてセッショントークンを通じて実装されます。クライアントがページをリクエストすると、サーバーは乱数のトークンを生成し、そのトークンをセッションに配置して、そのトークンをクライアントに送信します (通常は非表示のフォームを構築します)。次回クライアントがリクエストを送信すると、トークンがフォームとともにサーバーに送信されます。
その後、「アンチ csrf 攻撃」に適用される場合、サーバーはトークン値を検証して、セッション内のトークン値と等しいかどうかを判断します。等しい場合は、リクエストが有効であることを証明できます。鍛造する。
ただし、「フォームの重複送信防止」を適用した場合、サーバー側での1回目の検証が同じ後、ユーザーが繰り返し送信すると、2回目の検証判定が失敗します。ユーザーが送信したフォームのトークンは変更されていませんが、サーバー側セッションのトークンは変更されているためです。
上記のセッションアプリケーションは比較的安全ですが、同時に、複数のページと複数のリクエストがある場合、複数のトークンを同時に生成する方法を使用する必要があり、より多くのリソースを消費します。実行効率が低下します。したがって、セッショントークンの代わりに検証情報をCookieに格納する方法も利用できます。たとえば、「繰り返し送信」を処理する場合、最初の送信後に送信された情報が Cookie に書き込まれます。2 回目の送信では、Cookie にすでに送信記録があるため、2 回目の送信は失敗します。
ただし、Cookie ストレージには致命的な弱点があります (XSS 攻撃によりユーザーの Cookie が簡単に取得できる) と、再びゲームオーバーになります。ハッカーは直接 CSRF 攻撃を実行します。
つまり、安全性と効率性は相対的なものです。特定の問題に詳しく対処しましょう。
繰り返しの送信を防ぐために、トークンが PHP フォームに追加されます
原理は、ランダムな文字列を生成し、フォームを送信した後、この文字列を検証することです。これにより、他の人が自分でフォームを作成することを防ぐことができます。提出を不正行為したり、繰り返し提出したり、ダブルクリックして提出したりすること。
phpで実装された簡単なコードは次のとおりです:
<?php /* * PHP简单利用token防止表单重复提交 * 此处理方法纯粹是为了给初学者参考 */ session_start(); function set_token() { $_SESSION['token'] = md5(microtime(true)); } function valid_token() { $return = $_REQUEST['token'] === $_SESSION['token'] ? true : false; set_token(); return $return; } //如果token为空则生成一个token if(!isset($_SESSION['token']) || $_SESSION['token']=='') { set_token(); } if(isset($_POST['test'])){ if(!valid_token()){ echo "token error"; }else{ echo '成功提交,Value:'.$_POST['test']; } } ?> <form method="post" action=""> <input type="hidden" name="token" value="<?php echo $_SESSION['token']?>"> <input type="text" name="test" value="Default"> <input type="submit" value="提交" /> </form>
上記の方法はより簡単で、次のコードはより安全です。
Token.php
<?php /* * Created on 2013-3-25 * * To change the template for this generated file go to * Window - Preferences - PHPeclipse - PHP - Code Templates */ function getToken($len = 32, $md5 = true) { # Seed random number generator # Only needed for PHP versions prior to 4.2 mt_srand((double) microtime() * 1000000); # Array of characters, adjust as desired $chars = array ( 'Q', '@', '8', 'y', '%', '^', '5', 'Z', '(', 'G', '_', 'O', '`', 'S', '-', 'N', '<', 'D', '{', '}', '[', ']', 'h', ';', 'W', '.', '/', '|', ':', '1', 'E', 'L', '4', '&', '6', '7', '#', '9', 'a', 'A', 'b', 'B', '~', 'C', 'd', '>', 'e', '2', 'f', 'P', 'g', ')', '?', 'H', 'i', 'X', 'U', 'J', 'k', 'r', 'l', '3', 't', 'M', 'n', '=', 'o', '+', 'p', 'F', 'q', '!', 'K', 'R', 's', 'c', 'm', 'T', 'v', 'j', 'u', 'V', 'w', ',', 'x', 'I', '$', 'Y', 'z', '*' ); # Array indice friendly number of chars; $numChars = count($chars) - 1; $token = ''; # Create random token at the specified length for ($i = 0; $i < $len; $i++) $token .= $chars[mt_rand(0, $numChars)]; # Should token be run through md5? if ($md5) { # Number of 32 char chunks $chunks = ceil(strlen($token) / 32); $md5token = ''; # Run each chunk through md5 for ($i = 1; $i <= $chunks; $i++) $md5token .= md5(substr($token, $i * 32 - 32, 32)); # Trim the token $token = substr($md5token, 0, $len); } return $token; } ?>
form.php
<?php include_once("token.php"); $token = getToken(); session_start(); $_SESSION['token'] = $token; ?> <form action="action.php" method="post" <input type="hidden" name="token" value="<?=$token?>" /> <!-- 其他input submit之类的 --> </form>
action.php
<?php session_start(); if($_POST['token'] == $_SESSION['token']){ unset($_SESSION['token']); echo "这是一个正常的提交请求"; }else{ echo "这是一个非法的提交请求"; } ?>
この記事が、PHP プログラミングの皆様のお役に立てれば幸いです。
繰り返し送信を防ぐために PHP フォームにトークンを追加する方法の詳細については、PHP 中国語 Web サイトに注目してください。