2

私はたくさんグーグルで検索してきましたが、まだ答えがないので、ここでこの質問をすることにしました: スクリプトで受信しているデータがページ上の特定のフォームからのものであることを PHP で確認する方法はありますか? 私がデータベースにデータを保存するために使用しているスクリプトの名前を誰もが見ることができるので、私が尋ねているので、誰かが URL 全体を見つけることができれば、スクリプトに偽のデータを送信することもできます。データがマイページの適切なフォームから取得された場合にのみ、保存プロセスがトリガーされるという条件。

私はjQueryを使用してAJAX関数を呼び出しているので、基本的に「送信」ボタンをクリックすると、$.POST()メソッドがトリガーされ、データを保存するためのスクリプトが呼び出されます。

ありがとう、トーマス

4

4 に答える 4

2

トークンを使用してリクエストが有効かどうかを確認する

データを送信するときに、いつでも何らかのセキュリティ トークンを追加できます。

トークンは、さまざまな用途に簡単に拡張でき、リクエストが有効かどうかを確認する際に広い範囲をカバーできます。たとえば、重要でないフォームを公開して、ユーザーにいくつかのページから秘密鍵を取得するように依頼することができます (それらを強制します)。そのページを開くには)、データを送信するときにこれらのキーを使用してそれらを識別します。

もちろん、これはすべてユーザーに対して完全に透過的です。Cookie (またはセッション Cookie) を介してフロント ページからキーを提供できるためです。ここでは問題ではありません。サーバー キーは使用後に変更され、指定された時間内に無効になる必要があるため、多かれ少なかれセキュリティはありません。ユーザーの ID が変更されたとき)。
この使用例では、フロントページを開いたユーザーのみがサーバーにデータを送信できます。

もう 1 つのケースは、サーバーにデータを送信するためのフォームを含む同じページで Cookie が配布される場合です。ページを開くすべてのユーザーは、すぐにデータを送信するためのキーを持っていますが、誰かが外部からリクエストを行おうとすると失敗します。OWASP クロス サイト リクエスト フォージェリ と、codinghorror.com のブログ CSRF とあなた
を参照してください。

AJAXだけ?

別の質問に対する私の回答は次のとおりです。この回答では、追加のデータを ajax リクエストに挿入するためのさまざまな方法について説明しています: Liftweb: 従来の方法と AJAX の両方で送信できるフォームを作成します(

$.ajax({ 
    ... 
    data: /* here */ 
    ...

現在、私はこのようにトークンを使用しています:

送信に使用するフォーム

この非表示の入力はフォームに追加できますが、前述の別の回答で説明されている方法を使用できるため、必須ではありません。

<input type="hidden" name="formid" value="<?php echo generateFormId(); ?>" />

関数 generateFormId()

ランダムな文字列を生成してセッション ストレージに保存するだけです

function generateFormId() {
    // Insert some random string: base64_encode is not really needed here
    $_SESSION['FORM_ID'] = 'FormID'.base64_encode( uniqid() );
    // If you want longer random string mixed with some other method just add them:
    //$_SESSION['FORM_ID'] = 'FormID'.base64_encode( crypt(uniqid()).uniqid('',true) );
    return $_SESSION['FORM_ID'];
}

送信されたフォーム データの処理

if (!isset($_SESSION['FORM_ID']) || $_SESSION['FORM_ID'] != $_POST['formid']) {
    // You can use these if you want to redirect user back to form, preserving values:
    //$_SESSION['RELOAD_POST'] = $_POST;
    //$_SESSION['RELOAD_ID'] = uniqid('re');
    echo 'Form expired, cannot submit values.';
    //echo '<a href="form.php?reload='.$_SESSION['RELOAD_ID'].'">Go back and try again</a>';
    exit(1); // <== Stop processing in case of error.
}

データを送信しているフォームを確認する必要がある場合

次に、ID を生成するときにプレフィックスを追加し、フォーム データを処理するときにそのプレフィックスを確認することができます。

これは、1 つの php スクリプトが多くの異なるフォームを処理する場合です。


悪意のあるユーザーを防ぐための唯一の最終的な解決策は、サーバーからすべてのワイヤを引き抜くことであることを忘れないでください...

于 2012-05-06T11:20:14.623 に答える
1

これは興味深いトピックですが、重要な点が欠けています。スパムロボット/悪意のあるユーザーも、その特定のフォームページ(!)を使用してデータベースを爆撃する可能性があります。

したがって、問題は、リクエストがそのページからのものであるかどうかを確認する方法ではなく、彼が通常のユーザーであるか、ロボット/スパマー/ボットであるかを確認する方法です。

http://www.recaptcha.netのようなキャプチャでそれを行います

私が質問を少し誤解した場合:リクエストが「実際の」ユーザーからのものであることを確認したい場合は、ログインシステム/ユーザーシステムで作業し、ユーザーID /パスワードを(dbまたはセッションを介して)毎回確認する必要がありますdbリクエストを実行する時間。

于 2012-05-06T10:45:11.790 に答える
0

これをチェックして、ページが AJAX 経由でリクエストされていることを確認できます。

strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest'

HTTP_REFERERを確認することもできます。

しかし、脆弱なデータを処理するページを保護しようとしているようです。これには、上記の 2 つ以上のものが必要です。これに関する詳細情報を取得するには、「CSRF Forgery」をグーグルで検索することをお勧めします。

于 2012-05-06T10:56:35.873 に答える