Rails 2.0 の Cookie と、 RESTful でのセッション管理について
Rails 2.0 になってセッション Cookie の持ち方が変わった。 1.2 までは Cookie にセッション ID を書き込んで、対応するセッション情報をメモリ上に持っていたけど、 2.0 だと Cookie にそのままセッション情報を書き込むようになってる。 こうすると、アプリケーションサーバを分散させたときにセッション情報をシェアしなくてよくなる。 もちろん、 Cookie の中身はユーザが簡単に書き換えられるから、書き換えを検出するために HMAC をつけている。
んで、この方法でのセッションの持ち回りに落とし穴はないのかなぁ…と思って Twitter でつぶやいたら、意外と話が広がって面白かったのでここでまとめてみるよ。
machu Rails2.0 の Cookie 側にセッション情報を持つ方法だと、セッションタイムアウトはどうやるんだろ。自作かなぁ。
takahashim @machu タイムアウトというか、生成時刻も含めてやればサーバ側で好きなタイミングで reject できるはずでは。ユーザが自由に書き換えられないのがポイントなので。
machu @takahashim やっぱりコントローラでフィルタするコードを書くようになるんですね。
takahashim @machu flash 文字列ならそもそもタイムアウトは気にしなくてもいいような気もしますが、セッション保持用はタイムアウトさせといた方が安全でしょうし、そうするとコントローラではじくべきかなあ、と。
machu @takahashim はい。セッション保持のことを気にしていました。何も考慮しないと 1 年前の Cookie でログインできそうなので。
takahashim RESTful に考えるなら、セッション情報を保持するのではなく、 ID とパスワードを毎回送りつけるべきなんですよね。これが大前提]]
takahashim ただ、 ID とパスワードを送るのはいろいろ問題があるので、代わりにトークンを使うことができるようにする。その場合、トークンは期限つきの ID+ パスワードの代替物となる。
takahashim その期限が一回きりなのが Digest 認証だったり WSSE 認証で、時間単位で続くのがいわゆるクッキーを使ったセッション管理、……という認識でいいのかなあ。
takahashim 『 RESTful Web サービス』では 6.1.2 と 8.14.1 に書いてあるっぽい(まだ読了してない)
※ (追記) RESTful Web サービスを読んだら「8.17 ユーザはなぜ HTTP クライアントを信頼するのか」にも面白い議論が書かれていた
machu @takahashim たしかに。でもそうなると「重要な操作の前にパスワード入力」ができなくなりますね。
takahashim @machu 「重要な操作の前にパスワード入力」って amazon みたいな方法ですか?
machu @takahashim はい。そうです。パスワード変更時は他のサイトもそうですね。
takahashim @machu 再入力の問題は、 Web サービスのクライアントとサーバの間の問題ではなく、クライアントと人間(ユーザ)の間の問題じゃないかという気がしてきました。だもんで、 Web サービスのアーキテクチャとは直接的には関係のないことじゃないかと。
machu @takahashim REST の視点からはそうですね。でもセッション漏洩時の被害減少のためにはサーバ側でのチェックが必須だと思います。
machu アーキテクチャの美しさとセキュリティはトレードオフなのかなぁ。
takahachim @machu ふつうのセッション漏洩時の話については、おそらくトークンで、ということになると思います。 amazon みたいな再入力はまた別の話っぽい気がします。
machu @takahashim セッション漏洩対策のために再入力すると思っていたのですが、別の話というのがちょっと分からなかったです。
takahachim @machu 例えば amazon などの場合、離席時に勝手に購入したりしないように、というのもあると思います。そもそもセッション保持期間が長すぎなので。
machu @takahashim 理解しました。僕は離席問題とセッション漏洩はサーバ側から見たら同じと考えてました。 Windows のパスワードロックと同じですね。
machu @takahashim Windows のロックに頼るならトークン使わずに SSL+Basic 認証でよさそうです。
machu んーでも、ログイン後は SSL を使わないからせめてトークンなのかな。
machu そもそもなんで漏洩しやすい Cookie でセッション管理するんだっけ。 HTTP 認証のほうが漏洩しずらいのに。
tokuhirom @machu ログアウトできないというのが致命的な欠陥だったり……
machu HTTP 認証でログアウト処理 http://tinyurl.com/2xrdul
tokuhirom @machu ログイン画面がカスタマイズできないのが嫌というお客さんもいますね
machu @tokuhirom ログイン画面が分かりにくいって理由もあった気がします。
machu @tokuhirom 見事にかぶったw
machu HTML フォームに入れたパスワードを HTTP ヘッダで送る仕組みがあれば OK ?
machu CGI だと HTTP 認証を制御できないからという話もあったような。
machu REST 本を読むときはこの辺の話を考えるようにしようっと。
machu Rails のセッションから話が広がって面白かった。
machu JavaScript から HTTP 認証ヘッダを制御できないのはなんでだろ?( XHR を除く)
machu JS から HTTP 認証ヘッダを読めちゃダメだけど、設定できるようになってればいいのに。
takahashim @machu ブラウザのセキュリティモデルとして、ユーザの明示的な操作なしに勝手に認証情報が書き換わってしまうのは何か危険な気もします……あんまり深い考えではないですが。
takahashim CSRF 対策してあるサイト ( クッキーとは別にトークン利用とか ) に対しても、 iframe でトークン抜き出して JavaScript でそのトークンを利用して自動 POST 、みたいな攻撃ってできないんでしたっけ?
最後はなんだか RESTful 設計でのセッションの持ち方 (REST はステートレスなのでこの概念がすでに変かも?) という話になった。 Cookie でセッション管理するのが当たり前だと思っていたけど、 XSS 脆弱性の影響を受けない HTTP 認証を使った方が安全だよなぁ。