あめだまスマートフォン用の表示で見るあめだまこの広告は、90日以上更新していないブログに表示しています。CSRFJerseyのバージョン1.9.1で追加されたCSRFをステートレスに防ぐフィルタが興味深かったので、そのメモです。通常、CSRF攻撃を防ぐにはトークンを使う方法があります。サーバがクライアントにトークンを発行して、クライアントは発行されたトークンをクエリパラメータなどの形でリクエストに付与します。サーバはトークンが付与されていないリクエストを実行しません。攻撃者は発行されたトークンを知らないため、リクエストを実行できないという寸法です。CSRF対策とステートただし、この方法ではトークンの取得〜リクエストの発行にステートができるため、WebAPIがステートフルになってしまうという問題があります。RESTベースのWebAPIはやはりステートレスに作りたいところです。そこで、JerseyのCSRF対策フィルタはステートレスになるよう作られています。JerseyのCSRF対策フィルタフィルタのJavaDocとソースコードはこちら。http://jersey.java.net/nonav/apidocs/1.10/jersey/com/sun/jersey/api/container/filter/CsrfProtectionFilter.htmlhttp://java.net/projects/jersey/sources/svn/content/trunk/jersey/jersey-server/src/main/java/com/sun/jersey/api/container/filter/CsrfProtectionFilter.java?rev=5545フィルタのソースを見ると内容はとてもシンプルです。HTTPリクエストにX-Requested-Byヘッダがあればリクエストをそのまま通す、なければHTTPステータスに400(BadRequest)を返却します。HTTPメソッドGET,HEAD,OPTIONSは処理の対象から外しています。これでCSRF攻撃が防げるのかフィルタのJavaDocで以下のPaperを参照しています。imageなどからのリクエストではHTTPリクエストに独自のヘッダを付与することができません。独自のヘッダをつけるにはXMLHttpRequestを使うしかないわけです。Policyが適用されるため攻撃者のドメインからHTTPリクエストがくることはない、ということのようです。フィルタを試す実際にフィルタを使ってみます。フィルタをweb.xmlでサーブレットに登録します。<init-param><param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name><param-value>com.sun.jersey.api.container.filter.CsrfProtectionFilter</param-value></init-param>テストに使うリソースは以下の通り。Response.status(201).entity(message).build();}}テストは実際にHTMLを書いてAjaxを使うのも良いですがJerseyにはClientの実装があるためそれを使います。201);}}アプリケーションをサーブレットにデプロイした状態でテストを実行すると全てPASSしました。まとめCSRFを防ぐ方法として、通常のトークンを使うやり方ではWebAPIがステートフルになってしまうという問題点がありました。それに対し、HTTPリクエストに独自ヘッダをつけるやり方ではステートレスに防ぐことができます。この方法の注意点としてはWebAPIをコールするのがXMLHttpRequest経由に限られる、ということです。XMLHttpRequest以外からもコールされるようなWebAPIを作る場合には、やはりトークンを使ってステートフルにする方法をとるしかないと思います。OPTIONSがフィルタ処理の対象外になっていることも注意すべきです。そもそもWebAPIの設計として、それらのHTTPメソッドで副作用のある処理を実行するように作るべきではないです。トランザクションを管理する月別アーカイブはてなブログをはじめよう!momijiameさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。