1

でデモ アプリケーションをrails new demo作成し、 でスキャフォールディングされたユーザー コントローラーを生成しましたrails generate scaffold User name:string email:string。スキャフォールディングされたコードにはApplicationControllerwithprotect_from_forgeryがあり、 UserControllerwhich から派生したものもありますApplicationController

webrick を実行し、ユーザーを追加します。Authenticity トークンは、/users の POST で約束どおりに機能します。

まだRails 3.0.5を使用しているため、次のことができます。

niedakh@twettek-laptop:~$ telnet 10.0.0.4 3000
PUT /users/3 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 39

user[name]=vvvvv&user[email]=shiaus.pl

そして、トークンを与えずにユーザー 3 を変更します。

Started PUT "/users/3" for 10.0.0.4 at 2011-04-02 14:51:24 +0200
  Processing by UsersController#update as HTML
  Parameters: {"user"=>{"name"=>"vvvvv", "email"=>"shiaus.pl\r"}, "id"=>"3"}
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 3 LIMIT 1
', "updated_at" = '2011-04-02 12:51:24.437267' WHERE "users"."id" = 3s.pl
Redirected to http://10.0.0.4:3000/users/3
Completed 302 Found in 92ms

また、DELETE でも同じことができます。

DELETE /users/3 HTTP/1.1

それは私に与えます:

Started DELETE "/users/3" for 10.0.0.4 at 2011-04-02 15:43:30 +0200
  Processing by UsersController#destroy as HTML
  Parameters: {"id"=>"3"}
  SQL (0.7ms)   SELECT name
 FROM sqlite_master
 WHERE type = 'table' AND NOT name = 'sqlite_sequence'

  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 3 LIMIT 1
  AREL (0.5ms)  DELETE FROM "users" WHERE "users"."id" = 3

Redirected to http://10.0.0.4:3000/users
Completed 302 Found in 180ms

それらのリクエストと一緒にトークンを送信しないのに、なぜこれらのことができるのか説明していただけますか?

4

1 に答える 1

11

非常に短いバージョン:protect_from_forgery偽造された HTML FORM 要素からの XSRF 攻撃から保護するように設計されています。HTML フォームは PUT または DELETE を使用できないため、PUT および DELETE は XSRF 攻撃に対して脆弱ではありません。

XSRF (クロス サイト リクエスト フォージェリ) 攻撃とは、被害者のブラウザーがだまされて、ユーザーの操作なしに偽造されたリクエストをサーバーに送信することです。

より長いバージョン: これを行うことができる理由は、次のいずれかです。

  • セキュリティ/ログインが不要、または
  • すでにログインしており、同じドメインでホストされているスクリプトからリクエストを行っている、または
  • Fiddler または同様のものを介してリクエストを行っています (ブラウザの組み込みの保護をバイパスします)。

これらは、protect_from_forgery保護するように設計されたシナリオではありません。

の目的は、protect_from_forgeryXSRF 攻撃 (クロス サイト リクエスト フォージェリ) から保護することです。これは、悪意のある Web サイト (または悪意のある良い Web サイト) にアクセスしたユーザーが、だまされて別の Web サイトにリクエストを送信した場合に発生します。たとえば、次のように、訪問者をだまして GET リクエストを作成させることができます。

<img src="http://victim.com/victimPage?action=delete&id=ID12345" />

被害者が Evil サイトにアクセスするとすぐに、ブラウザは自動的に画像を取得しようとします。これは明らかに画像を取得しませんが、その間にvictim.comはアイテムID12345を削除するリクエストを実行します. POST も同様の方法で偽造できます。フォームを作成し、スクリプトを使用してそれを外部サイトに送信するか、ユーザーをだましてクリックさせて送信させます。

そこでprotect_from_forgery出番です。サーバーは、フォームの非表示フィールドでトークンをクライアントに送信します。有効なトークンが表示されない場合、サーバーは、送信されたフォームがサーバーによって送信された本物のフォームの送信ではないと判断するため、リクエストは偽造の可能性があるとして拒否されます。

しかし、あなたはそれを知っていました。

ポイントは、HTTP フォームはメソッド GET と POST のみを使用でき、PUT や DELETE は使用できないということです。これには 2 つの効果があります。

  • まず、PUT または DELETE を取得すると、トークンを配置する場所がありません。protect_from_forgeryPUT または DELETE はフォーム送信の結果ではないため、サーバーがトークンをクライアントに送信する方法はありません。そのため、クライアントにはトークンが返されません。
  • 第 2 に、HTML フォームは POST と GET しか使用できないため、リクエストが PUT または DELETE の場合、攻撃者は HTML フォームを使用して、ユーザーにリクエストを送信させるよう強制したり、騙したりすることはできません。それらは XMLHttpRequest を使用できますが、XMLHttpRequest はクロスサイト要求を許可しません (両方のサイトのセキュリティ設定で有効にされていない限り)。

これは、ホストしているドメインに悪質なコード自体が含まれていなければ、PUT と DELETE を偽造から保護する必要がないことを意味します。サーバーに悪意のあるコードが含まれている場合、攻撃者は任意の XMLHttpRequest リクエストを作成して有効なトークンを取得できるため、偽造防止を簡単に回避できます。

XSRF の簡単な説明については、ここを試してください。

于 2011-04-09T17:07:47.970 に答える