0

これがそれほど難しくないことを願っていますので、ここにストーリーがあります。要求されたときにJSONオブジェクトとして送信される単純なプロセスを作成しましたが、セキュリティ上の理由から、ファイルのコンテンツを保護(403)したい場合はブラウザに完全なURLを配置することでアクセスできます。

これが私のajax.php内のスクリプトです

<?php
$image = array(
"/trial/images/1.png",
"/trial/images/2.png",
"/trial/images/3.png",
"/trial/images/4.png"
);
  $msg = array(
    'status' => 1,
    'message' => 'Remember to +1',
    'html' => '<p>Thank you for downloading our software <img src="'. $image[array_rand($image)] .'" width="80" height="80" alt="Thank You"></p>'
  );
  echo json_encode($msg);
?>

これは、JSONオブジェクトを取得するためにajaxを使用してそのファイルにPOSTするために使用している関数のスクリプトです。

function custom_reminder(aElem){
    theLink=$(aElem).attr("href");
    $.ajax({
        type:"POST",
        url:"/includes/ajax.php",
        data:"action=reminder&thepath="+theLink,
        dataType:"json",
        error:function(){window.location=theLink;},
        success:function(msg){
            if(msg.status == 1) {
                display_reminder(msg.html,theLink);
            }else{
                custom_message(msg.message,"error");
                }
        }
    });
}

助けてください

4

3 に答える 3

4

このストーリーは、AJAX リクエストによる CSRF (クロス サイト リクエスト フォーギブリ攻撃) を防止する必要があります。

  1. いくつかのヘッダー データを配置し、クライアントで要求されたものを確認できます。
  2. セッションを使用してクライアントからのデータをチェックし、それをサーバー上のセッションと比較して ajax リクエストでアクセスします。
  3. コードstrtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')を追加して、ajax から xmlhttprequested であることを確認します
  4. サーバーから機密データを送信し、時間制限付きでクライアントに保存する場合は、いくつかのトークンを生成します

トークンの使用例:

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. OWASPX/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/

  1. 次のように、JAVASCRIPT を介してコードの INJECTION から保護します。

    $output = preg_replace('/(<(form|FORM)[^>]*(method|METHOD)="(post|POST)"[^>]*>)/',  
                     '$0<input type="hidden" name="' . self::$token_name . '" value="' . self::$token . '">', $output);  
    
  2. データの盗聴や閲覧を防ぐために、JSON データを使用して送受信するときに SSL データ転送を行います。

  3. 内容に基づいてヘッダーにハッシュなどのデジタル署名を入れます。コンテンツをハッシュして、たとえばヘッダー ファイル「Digital-Sign: md5-data」に入れます。コンテンツをハッシュし、デジタル署名の新しい変数としてヘッダーに入れる必要があります。データをチェックし、チェックのためにハッシュを使用して比較するクライアントは true です。送信データのタイムスタンプなどのソルトと組み合わせることができます。md5($timestasmp.$content)

于 2013-03-08T12:32:36.623 に答える
1

リファラーを確認できます。同じホストからのものである場合は、JSON ファイルを提供します。それ以外の場合は、403 を提示します。

他のオプションは、異なる値のハッシュに基づいて、シークレットを使用することができます。それらを AJAX リクエストで送信し、PHP ファイルでチェックします。

于 2013-03-08T12:19:27.483 に答える
0

セッションを使用します。

$_SESSION['key'] = 'randomcode';

このキーの暗号化されたバージョンを AJAX 呼び出しに送信します。

AJAX スクリプトで、受信したキーをセッションと照合します。一致する場合は、ダウンロード ページにアクセスしたユーザーからの要求であることがわかります。

于 2013-03-08T12:27:25.550 に答える