Tech Racho エンジニアの「?」を「!」に。
  • 開発

Rails 6のcookieに「purpose」メタデータが追加(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Rails 6のcookieに「purpose」メタデータが追加(翻訳)

Action Dispatchが提供するcookies.signedcookies.encryptedは、ユーザーによるcookie値の不正な改変を防ぐのに利用できます。

# ユーザーがcookie値を改変できないようにする
cookies.signed[:proxy_id] = current_admin.id

# このときのクライアント側のcookieの中身
# MTAx--fd47225e9e6de0710a4f84104d73fec1e4d94c65

# cookie値の改変だけでなく読み出しもできないようにする
cookies.encrypted[:current_zip] = current_user.zip

# このときのクライアント側のcookieの中身
# aHNzb2dxVkN1bE1MQTd0MnFsSkZ2dz09LS1tM2NHcVZQbjRoT0RVOVdvdE9FdHZnPT0%3D--be007d00dda3678f79fda9d2a7bcfacc6a760919

何が問題だったか

Rails 6より前は、上述のメソッドでcookieの中身しか署名されず、名前には署名されていませんでした。

このため、あるcookieから別のcookieに署名済みデータをコピペされる可能性があるというセキュリティ上の脆弱性がありました。

#17136で、cookieの値をコピーして別のユーザーのところで使える可能性がある例が示されました。

Rails 6以後

Rails 6では、#32937purposeメタデータがcookieに追加されました。

このメタデータではcookieの名前が設定に使われ、それがcookieに埋め込まれます。

これによって、あるcookieの値を別のところにコピペされることを防止します。

cookies.signed[:proxy_id] = current_admin.id

# このときのクライアント側のcookieの中身
# eyJfcmFpbHMiOnsibWVzc2FnZSI6Ik1UQXgiLCJleHAiOm51bGwsInB1ciI6ImNvb2tpZS5wcm94eV9pZCJ9fQ%3D%3D--ac22ece5b73ea1fbd3de8e925be57a173e9f8a2b

上の例では、--より前のデータはBase64でエンコードされた値で、そこにpurposeメタデータとexpiryメタデータが埋め込まれています。

このメタデータが設定されていない従来のcookieについては引き続き配慮されます。

この機能をあえて外したい場合は以下の設定が使えます。

config.action_dispatch.use_cookies_with_metadata = false

この設定はデフォルトでtrueになります。

関連記事

Ruby 2.7: ハッシュからキーワード引数への自動変換が非推奨に(翻訳)

CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。