17

私は PHP でログイン スクリプトを作成する初心者です。これは、私がこれまでに持っているフォーム トークン ステートメントです。

$_SESSION["form_token"] = md5(rand(time (), true)) ;

このステートメントは、ユーザーがログインしたいことを示した直後に発行されます。

私の限られた理解では、トークンの目的は、一意の時点で一意のユーザーを識別し、フォーム トークン情報を偽装することです。

その後、すべてが曖昧になります。これが私の3つの未解決の質問です。

  1. セキュリティ目的でフォームトークンを「チェック」するのに最適な時期はいつですか?

  2. どうすれば確認できますか?

  3. フォームトークンを「破棄」するのはいつですか? (IOW、ユーザーがログアウトするまでフォームトークンは「アクティブ」のままになりますか?

4

3 に答える 3

19

これはCSRF攻撃を防ぐためです

http://en.wikipedia.org/wiki/Cross-site_request_forgery

悪意のあるサイトは、理論的には、アプリケーションに投稿するフォームを表示する可能性があります。フォームには、データ侵害や望ましくないアクションを引き起こす指示が含まれている可能性があります。ユーザーはすでにログインしているため、アプリが受け入れるフォームを送信するようにだまされる可能性があります。フォームトークンは、フォームが他のサイトではなく、あなたのサイトによって作成されたことを保証します。

多くの場合、HTTP_REFERER を確認するだけで十分ですが、完全な解決策ではありません (たとえば、https はリファラー文字列を送信しません)。

本当にすべてのフォームをトークンで保護したい場合は、emitToken() や checkToken() などの便利な関数を作成して、サイト全体で機能させることができます。

いくつかの例:

http://phpsec.org/projects/guide/2.html

http://www.rodsdot.com/php/CSRF_Form_Protection.php

于 2010-01-09T17:54:03.607 に答える
15

あなたが試みていることをする必要はありません。PHP で session_start() を使用してセッションを開始すると、一意の SESSIONID が既に生成されています。これをフォームに入れるべきではありません。デフォルトでは、Cookie を介して処理されます。SESSIONID もチェックする必要はありません。これも処理されます。

ユーザーを認証し、認証された ID を保存する責任があります (たとえば、$_SESSION['user_id'] = $userId を SESSION に保存します。ユーザーがログアウトすると、session_destroy でセッションを破棄します。

session_start() が、サイト内のすべてのページの最初のものの 1 つであることを確認する必要があります。

以下に基本的な例を示します。

<?php
session_start(); // starts new or resumes existing session
session_regenerate_id(true); // regenerates SESSIONID to prevent hijacking

function login($username, $password)
{
    $user = new User();
    if ($user->login($username, $password)) {
        $_SESSION['user_id'] = $user->getId();
        return true;
    }
    return false;
}

function logout()
{
    session_destroy();
}

function isLoggedIn()
{
    return isset($_SESSION['user_id']);
}

function generateFormHash($salt)
{
    $hash = md5(mt_rand(1,1000000) . $salt);
    $_SESSION['csrf_hash'] = $hash
    return $hash;
}

function isValidFormHash($hash)
{
    return $_SESSION['csrf_hash'] === $hash;
}

編集:元の質問を誤解しました。フォーム ハッシュを生成および検証するために、上記の関連するメソッドを追加しました。

次のリソースを参照してください。

于 2010-01-09T17:55:54.210 に答える
0

Zend フレームワークの実装を確認できます。

特定の実装とは別に、ドキュメントでは、フォームでのこの種の要素の理由と使用法について説明しています。

その Zend_Form_Element_Hash https://docs.zendframework.com/zend-form/element/csrf/

于 2010-01-09T18:06:08.253 に答える