じぶんメモ

プログラミングのメモ、日常のメモとか。

CSRF対策

CSRFとは

クエスト強要(CSRF:Cross-site Request Forgery)。 本来拒否すべき、外部のWebページからのHTTPリクエスト(POSTやGET)によって、
Webサイトの何らかの機能が実行されるというもの。
ユーザが罠を踏んで、ECサイトで勝手に買い物をされるといったことが考えられる。

Cookieを使ってセッションを搬送しているアプリケーションや、Basic認証を用いているWebアプリケーションが対象となる。
つまり、トランザクション投入のきっかけとなったフォーム画面が
自サーバから供給(POST)されたものであることを確認していないアプリが攻撃の対象。

CSRF対策

GET送信よりもPOST

GETはURLにすべての情報を載せて送るリクエスト方法のため、
GETの受付はPOSTに比べて多くの攻撃手段を提供してしまうことになる。
また、POSTは通常キャッシュに残らないため、
hiddenフィールドに格納したトークンがキャッシュに残ってしまう可能性を下げることができる。 ただしPOSTの方がマシ、というレベルだとか。

ワンタイムトークンの使用

フォームが読み込まれた際に、フォームにトークンを埋め込み、
フォームデータをPOSTした際に、サーバー側で、POSTされたトークンとフォームのトークンの値を照合。
一致していれば正規の画面から送信されたリクエストだと判別できる。

  • ASP.NET MVC ではValidateAntiForgeryTokenを使用して実装する。
<%=Html.AntiForgeryToken() %>
<input type="submit" value="Create" />
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken()]
public ActionResult Create(Book b, FormCollection collection) {
    return View();
}
  • Railsではprotect_from_forgeryが同様の役割を果たす。
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
end