web-dev-qa-db-ja.com

jQuery .ajax()にCSRFトークンが必要ですか?

基本的な.ajax()POSTメソッドをPHPファイルに追加しました。

どのようなセキュリティ対策が必要ですか?

周りのいくつかの投稿は、AJAX=を介して送信し、PHPファイルで検証します。これは十分な方法ですか?

28
Nathan Waters

CSRFのリスクは、外部サイトからデータが送信され、ユーザーのブラウザーが認証Cookieを自動的に送信することです。

必要なのは、受信アクション($.ajax()メソッドが送信するPOSTデータ))がリクエストが別のページから来たことを確認できるようにする方法です外部サイトではなく、サイト。

これを行うにはいくつかの方法がありますが、推奨される方法は、確認できるトークンとハッカーが到達できないトークンをリクエストに追加することです。

最も簡単なもの:

  • ログオン時に長いランダム文字列トークンを作成し、ユーザーに対して保存します。
  • トークンを含む$.ajax()リクエストにパラメーターを追加します。
  • 要求に応じて、トークンがユーザー用に保存したトークンと一致することを確認します。
  • トークンが一致しない場合、CSRFハックがあります。

ハッカーはDBにアクセスできず、ユーザーに送信したページを実際に読み取ることができないため(XSS攻撃を受けない限り、それは別の問題です)、トークンを偽装することはできません。

トークンで重要なのは、予測できる(および検証)であり、ハッカーができないであるということです。

このため、長くランダムなものを生成してDBに保存するのが最も簡単ですが、代わりに暗号化されたものを構築することもできます。しかし、私はユーザー名をMD5にするだけではありません-CSRF攻撃者がトークンを生成する方法を見つけた場合、ハッキングされます。

別の方法は、トークンを(データベースではなく)Cookieに格納することです。攻撃者はCookieを読み取ったり変更したりすることができず、Cookieを再送信するだけです。次に、HTTP POSTデータはCookieのトークンと一致します。

これらをより洗練されたものにすることができます。たとえば、正常に使用されるたびに変わるトークン(再送信を防止する)や、ユーザーとアクションに固有のトークンですが、それが基本的なパターンです。

36
Keith

リクエストの偽造に関しては、クライアントがどのようにリクエストを送信するかは関係ありません。 ajaxの投稿には、他の種類の投稿と同じCSRFルールが適用されます。

CSRF防止チートシート を読むことをお勧めします。ユーザーごとのシークレットトークンを使用することが、最も一般的な保護方法です。

2
rook

トークンは必要ありませんが、状態を変更する機能をCSRFから保護する必要があります。

これを行う簡単な方法の1つは、AJAXリクエストで送信されるヘッダーを追加することです。ランダムトークンは不要です。

これは次の理由で機能します。

  • HTMLフォームには、攻撃者がカスタムヘッダーを追加することはできません。
  • CORSを有効にしないと、カスタムヘッダーをドメイン間で渡すことはできません。

もちろん、サーバー側のコードは、アクションを実行する前にヘッダーが存在することを確認する必要があります。

詳細: X-Requested-Withヘッダーのポイントは何ですか?

1
SilverlightFox

Djangoで試すことができる簡単なデモを次に示します。

HTMLページ上

{%block content%}
<form id="userForm">
{%csrf_token%}
  <input type="text" id="username" placeholder="User Name">
  <input type="password" id="password" placeholder="Password">
</form>
{%endblock%}

Javaスクリプトコード

%(document).on('submit','#userForm',function(e){
   e.preventDefault();

 $.ajax({

    type = 'POST',

    url:'path/to/url',

    data:{
     username:$('#username').val(),
     password:$('#password').val(),
     csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken').val()
    },

   success:function(data){
       alert('Successfull');
   }
  });

});
0
user7032676