web-dev-qa-db-ja.com

Rails:csrf_meta_tagの仕組み

私はPHP開発者の学習Ruby on Rails by Michael Hartl's tutorial 。以下は、本からの引用です。csrf_meta_tag

... Rails method csrf_meta_tag [防止]クロスサイトリクエストフォージェリ(CSRF)、悪意のあるWeb攻撃の一種。詳細については心配しないでください(私はしません)。 Rails=はアプリケーションを安全に保つために懸命に働いていることを知っているだけです。

事は、私は本当に興味があります。挿入csrf-paramおよびcsrf-tokenメタタグはCSRFを防ぎますか?グーグルを試してみましたが、何も見つかりませんでした。

62
Nick

csrf_meta_tagは基本的に非表示フォームフィールドと同じことを実現していますが、フォームに関連付けられていないjavascriptリクエストにトークンを取得する簡単な方法を提供するためにあります。

jquery-ujs ライブラリを使用する場合、そのメタタグのコンテンツは、作成されたAjaxリクエストに(リクエストヘッダーとして)自動的に追加されます。

74

csrf_meta_tagは本質的にデジタル署名であるものをページに挿入し、アプリケーションサーバーに着信するリクエストが実際に適切にログインしたユーザーからのものであることの検証として機能します。これは、クロスサイトスクリプティング(別のタブでGMailにログインしているときに、GMailなどの要求を発する完全に無関係なページ上のスクリプト)を防ぐのに役立ちます。

csrf_meta_tag自体は、無関係なページがGMail(または攻撃の標的となる他のサービス)へのリクエストを発射することを防ぎませんが、csrf_meta_tagは、上記のリクエストの有効性を検証するために使用されます。無効なリクエスト(クロスサイトスクリプティングの試行など)は検証に失敗するため、破棄されます。

別の言い方をすれば、攻撃者の観点から:

csrf_meta_tagsが存在しました(Railsに限定されません)、クロスサイトスクリプティング攻撃が成功すると、悪意のあるサイトがリクエストを表示する方法でデータをWebアプリに送信できましたユーザーの代わりに行われているかのように、Webサービスの管理者で、あるブラウザータブでそのサービスの管理パネルにログインしているとします。サービスを攻撃すると、悪意のあるサイトは、データベースからユーザーのリストをダンプしたり、他の機密データを盗んだり、サービスに含まれるデータを害したり、破損したり、破壊したりするなどの管理リクエストを行うスクリプトを実行できます(サーバーの観点から)管理者自身からの有効なリクエストであるように見えますが、csrf_meta_tagは、リクエストに署名し、そのような試みが成功するのを阻止する方法です。

より詳細な説明があります こちらから入手可能

Railsで生成されたページの1つで「ソースの表示」を行うことも教育的であり、CSRFタグがどのように見えるかがわかります。

55
jefflunt

Railsでこのように動作します

def csrf_meta_tags
    if protect_against_forgery?
      [
        tag('meta', :name => 'csrf-param', :content => request_forgery_protection_token),
        tag('meta', :name => 'csrf-token', :content => form_authenticity_token)
      ].join("\n").html_safe
    end
  end

クリックすると詳細が表示されます

また、チェックする必要があります Ruby on Rails Security Guide

こちらがニースです ブログ

しかし-私はNational Vulnerability Databaseを好む、ここに良い説明があります

CWE-352:クロスサイトリクエストフォージェリ(CSRF)

CWE-79:Webページ生成中の入力の不適切な中和(「クロスサイトスクリプティング」)

CWE-Common Weakness Enumerationについては、このドキュメントを確認してください

14
AMIC MING

csrf_meta_tagsは、Ajaxリクエストがフォームパラメーターの1つとしてこれらを使用してサーバーにリクエストを送信することを示します。 Railsは、フォームボディ(params)の一部としてcsrfがリクエストを処理することを期待します。これらのメタタグを使用して、ニーズに合わせてフォームボディまたはcsrfヘッダーを構築できます。あなたの質問に役立ちます。

4
praveenag

ヘルパーの出力csrf_meta_tags

<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="J/gw2ePXHS9Z1SUSSeUQgMmPhsPEFlFbMrLTLFHLfKjeWh7g4uyOnBlfKnlZlmCBiALDWdDWCSo1z0tybGVtfA==" />

このトークンは、ajaxリクエストに含めることができます。例( jquery-ujs ):

https://github.com/Rails/jquery-ujs/blob/4b6e30f68ff1244fc0c790641d3408c2695a29bd/src/Rails.js#L7

    csrfToken: function() {
     return $('meta[name=csrf-token]').attr('content');
    },

    // URL param that must contain the CSRF token
    csrfParam: function() {
     return $('meta[name=csrf-param]').attr('content');
    },

    // Make sure that every Ajax request sends the CSRF token
    CSRFProtection: function(xhr) {
      var token = Rails.csrfToken();
      if (token) xhr.setRequestHeader('X-CSRF-Token', token);
    },
1
artamonovdev