iris

OmniAuth 利用時に注意したい CSRF 対策と CORS 問題


OmniAuth を使用した際のメモです

リクエストフェーズの開始

OmniAuth では /auth/:provider というリンクを設置し、そこにアクセスすると認可URLを生成してリダイレクトしてくれます

GET リクエストの問題点

このリンクを設置する際に、リクエストが GET の場合は 404 エラーが発生します

これは /auth/:provider がデフォルトで POST を要求しているためです

https://github.com/omniauth/omniauth/blob/e23567ac860f4adfb425db226d68a03235078941/lib/omniauth.rb#L50

以下のように GET リクエストを許可することも可能ですが、CSRF の危険性があるため、POST のみに制限することが推奨されます

OmniAuth.config.allowed_request_methods = [:get, :post]

CVE-2015-9284 の関連性

OmniAuth が POST リクエストを推奨している背景には、以下の脆弱性が関係しています

https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284

この脆弱性を防ぐには以下の対応が必要です.

omniauth-rails_csrf_protection は Rails の verified_request? メソッドを使用しているようで

https://github.com/cookpad/omniauth-rails_csrf_protection/blob/main/lib/omniauth/rails_csrf_protection/token_verifier.rb#L37

GET リクエストを許可してしまうと verified_request? が true になってしまい token の検証が行われないようです

https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/metal/request_forgery_protection.rb#L462

ここでチェックしてるみたいです

https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/metal/request_forgery_protection.rb#L500

CORS 問題

POST リクエストを推奨していますが、実際に POST を使用した場合に一部で問題が発生しました.

turbo を使用していたため、POST リクエストの際に CORS エラーが発生していました.

ブラウザが自動的に発行する Preflight request が原因のようでした.

/auth/:provider の POST リクエスト自体は自サーバーに向けられますが、その後 OmniAuth が外部サーバーへリダイレクトします.

Preflight request が発生した理由が、Turbo が何か先読みして引っかかったのかは謎ですが、Turbo を無効にすることで回避できました.

data: { turbo: false }

リクエストフェーズだけでも、CSRF や CORS といった注意すべき点が多くありなかなか大変でした…