このストーリーは、AJAX リクエストによる CSRF (クロス サイト リクエスト フォーギブリ攻撃) を防止する必要があります。
- いくつかのヘッダー データを配置し、クライアントで要求されたものを確認できます。
- セッションを使用してクライアントからのデータをチェックし、それをサーバー上のセッションと比較して ajax リクエストでアクセスします。
- コード
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
を追加して、ajax から xmlhttprequested であることを確認します
- サーバーから機密データを送信し、時間制限付きでクライアントに保存する場合は、いくつかのトークンを生成します
トークンの使用例:
function checkToken( $userId, $eventIdentificator, $token){
if( $token == sha1( $some_value_grabbed_from_time )){
return true;
}
}
return false;
}
5. 生成されたキーを使用してデータを要求するための時間制限ユーザーを追加します。これにより、今後 GET でこのハッシュ キーを使用して攻撃を防ぐことができなくなります。
生成トークンの例:
protected static function _generateToken()
{
$token = sha1(mt_rand(0, 1000000));
$_SESSION[$token] = time();
return $token;
}
そしてそれを次のように検証します:
if ($_SESSION[$token] >= time() - 7200) {
$valid = true;
}
6 . IT セキュリティで示されているように、COOKIE を組み合わせて ajax に追加できます。 ajax 呼び出し
7 。単純なクラスとして示されている Github の例を見てください: https://github.com/foxbunny/CSRF4PHP
また ...
public function generateToken() {
// Create or overwrite the csrf entry in the seesion
$_SESSION['csrf'] = array();
$_SESSION['csrf']['time'] = time();
$_SESSION['csrf']['salt'] = $this->randomString(32);
$_SESSION['csrf']['sessid'] = session_id();
$_SESSION['csrf']['ip'] = $_SERVER['REMOTE_ADDR'];
// Generate the SHA1 hash
$hash = $this->calculateHash();
// Generate and return the token
return base64_encode($hash);
}
protected function checkTimeout($timeout=NULL) {
if (!$timeout) {
$timeout = $this->timeout;
}
return ($_SERVER['REQUEST_TIME'] - $_SESSION['csrf']['time']) < $timeout;
}
public function checkToken($timeout=NULL) {
// Default timeout is 300 seconds (5 minutes)
// First check if csrf information is present in the session
if (isset($_SESSION['csrf'])) {
// Check the timeliness of the request
if (!$this->checkTimeout($timeout)) {
return FALSE;
}
// Check if there is a session id
if (session_id()) {
// Check if response contains a usable csrf token
$isCsrfGet = isset($_GET['csrf']);
$isCsrfPost = isset($_POST['csrf']);
if (($this->acceptGet and $isCsrfGet) or $isCsrfPost) {
// Decode the received token hash
$tokenHash = base64_decode($_REQUEST['csrf']);
// Generate a new hash from the data we have
$generatedHash = $this->calculateHash();
// Compare and return the result
if ($tokenHash and $generatedHash) {
return $tokenHash == $generatedHash;
}
}
}
}
// In all other cases return FALSE
return FALSE;
}
}
このソース コードは、サイド Ajax リクエストに対する CSRF 攻撃を防止するためのベスト プラクティスを示しています。フォームから送信された生成データの get/post をチェックし、PHP オブジェクトに静的変数 ( _generateToken()
)として置かれたハッシュと比較します。
8. OWASP
X/CSRF を介した攻撃の使用可能な例と、それらを防止するための使用可能な例を Web アプリケーション プロジェクトから示します。
リンク: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
ほとんどの場合、原則として、スクリプトがランダムに生成されたIDをリクエストごとに送信し、送信された以前の変数と新しい変数から比較する場合、「Cookieを二重送信」します。
9 . ランダムな文字列で攻撃をテストするための独自のスクリプトを作成するか、SHA512 を使用してより強力な攻撃を行うか、ダウンロードをテストのみに使用します: https://www.owasp.org/index.php/Category:OWASP_CSRFTester_Project
10. いくつかの HTTP HEADER ダミー データをラウンドの例 time() で追加し、例を今日の ODD または EVEN 日または ODD/EVEN 時間/分と比較します....
11 . 1 つの IP アドレスから頻繁に攻撃された場合 (例: 3 分間)、管理者に警告するか、一時的なリモート ホストをブロックします。
12 . X/CSRF がどのように機能するのかまだわからない場合は、YT のビデオの例をご覧ください: http://www.youtube.com/watch?v=pDXTDR6xew8
13 . crypt()
使用方法とOLD SCHOOL CSRF防止の使用方法を知りたい場合は、例として使用します: http://phpmaster.com/preventing-cross-site-request-forgeries/
または簡単なコード:
session_start();
switch($_GET["action"]) {
case "login":
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$user = (isset($_POST["user"]) &&
ctype_alnum($_POST["user"]) ? $_POST["user"] : null;
$pass = (isset($_POST["pass"])) ? $_POST["pass"] : null;
$salt = '$2a$07$my.s3cr3t.SalTY.str1nG$';
if (isset($user, $pass) && (crypt($user . $pass, $salt) ==
crypt("admintest", $salt))) {
$_SESSION["user"] = $_POST["user"];
}
}
break;
case "logout":
$_SESSION = array();
session_destroy();
break;
}
header("Location: login.php");
14 . CODEIGNITER/KOHANA の場合、ユーザーは HOOKS (すべてのクラスの前にクラスとしてロード) を介して簡単に使用できます。インジェクション コードの例: http://net.tutsplus.com/tutorials/php/protect-a-codeigniter-application-against -csrf/
次のように、JAVASCRIPT を介してコードの INJECTION から保護します。
$output = preg_replace('/(<(form|FORM)[^>]*(method|METHOD)="(post|POST)"[^>]*>)/',
'$0<input type="hidden" name="' . self::$token_name . '" value="' . self::$token . '">', $output);
データの盗聴や閲覧を防ぐために、JSON データを使用して送受信するときに SSL データ転送を行います。
内容に基づいてヘッダーにハッシュなどのデジタル署名を入れます。コンテンツをハッシュして、たとえばヘッダー ファイル「Digital-Sign: md5-data」に入れます。コンテンツをハッシュし、デジタル署名の新しい変数としてヘッダーに入れる必要があります。データをチェックし、チェックのためにハッシュを使用して比較するクライアントは true です。送信データのタイムスタンプなどのソルトと組み合わせることができます。md5($timestasmp.$content)