2017-08-30 20 views
0

私は、CSRF攻撃に対する2つの主要な解決策があることを知っています。セッションあたりの複数のブラウザタブでPHPのCSRF攻撃から保護

  • つのトークンすべてのユニークなフォーム

ため

  • トークンは、私は2番目のものを選びましたが、問題があります。ビジターが2つのタブでフォームを開くと、2番目のタブのフォームトークンが前のトークンを上書きします。私はこの問題を解決するためのコードを書いた。私の質問です:それは良い解決策ですか、あるいは私はそれに取り組まなければなりませんか? (例では、単に最も重要な部分があります。)

    ##### CONFIG & FUNCTION.PHP ##### 
    // INITIALIZING - RUN ONLY ONCE 
    $_SESSION["csrf_tokens"]["postcomment"]  = array(); 
    $_SESSION["csrf_tokens"]["postcommentedit"] = array(); 
    // etc, etc. 
    function makearandomtoken() 
    { 
        // a simple but secure way 
        return bin2hex (openssl_random_pseudo_bytes (32)); 
    } 
    
    ##### POSTCOMMENT_FORM.PHP ##### 
    // new form for comment under a post, so create a new token 
    $created_token = makearandomtoken(); 
    array_push ($_SESSION["csrf_tokens"]["postcomment"], $created_token); 
    // the form (only with important parts) 
    print "<form>\n"; 
    print "<input type=\"hidden\" name=\"token\" value=\"$created_token\">\n"; 
    print "</form>\n"; 
    
    ##### POSTCOMMENT_EXECUTE.PHP ##### 
    // get the token from POST variable 
    $received_token = filter_input (INPUT_POST, 'token', FILTER_UNSAFE_RAW); 
    // check it 
    if (in_array($received_token, $_SESSION["csrf_tokens"]["postcomment"])) 
    { 
        // VALID token, disable it 
        $token_index = array_search($received_token, $_SESSION["csrf_tokens"]["postcomment"]); 
        unset ($_SESSION["csrf_tokens"]["postcomment"][$token_index]); 
    } 
    else 
    { 
        // INVALID token -> CSRF attempt 
        die(); // or do anything 
    } 
    
  • +0

    アプリが2つのタブを開く必要がある場合は、ログインごとに1つのCSRFトークンを行います。そうでない場合は、複数のタブを開いてはいけません。また、トークンを設定するのは、フォームをこのように表示すると、非フォームベースのページに対して複数のタブを持つことができます。 –

    +0

    いいですね。欠落しているのは、未使用の古いトークンをパージする戦略、および/またはユーザーあたりの有効なトークンの量の制限です。 – jh1711

    +0

    トークンの量を制限する必要があります。そうしないと、攻撃者はトークンを使用してセッションを完了できません。また、セッションのサイズはPHPスクリプトのメモリ制限によって制限されるため、複数のアカウントでサーバーをDoSする可能性があります。 – Jarzon

    答えて

    0

    フォームのインスタンスごとに新しいトークンをしたい場合、私は、あなたの実装に問題が表示されません。両方のタブが正当にユーザーによって開かれたので、両方のトークンが受け入れられることは意味があります。

    CSRFの保護については、そのままであると思います。 3番目のサイトはトークンを持たずにユーザーを偽装することはできず、2つまたは3つの有効なトークンを持つユーザーは、攻撃者にとってタスクを容易にしません。

    フロントエンドをコーディングする場合は、document onUnload eventにイベントハンドラを登録し、ハンドラに、どのトークンがアンロードされているかをサーバーに通知するPOST要求を行うことができます。このようにして、バックエンドはトークンをセッションから削除することができます。ユーザーがブラウザの「戻る」ボタンを押すと、無効なトークンを再読み込みし、フォームを送信するときにエラーに苛まれることになります。

    関連する問題