QA@IT
«回答へ戻る

追記への回答を追加

887
 BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。`session[:user_id]`的な識別子が欲しい場合`request.env['Authorization']`を適宜パースすればよさそうです。
 
 また、もしも4KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合は`Rails session ActiveRecordStore`あたりで調べていただければ良いかと思います。
+
+------------------
+
+# 以下、追記への回答です
+
+@ursm さんから指摘があって回答を変更しました。cookieサイズ(=通常のセッションサイズ)の上限は4KBでした。とても小さいですね。とはいえ、実用上は特に困らないというのは相変わらずです。
+
+> 良く Rails で session[:user_id] みたいなコードを見るのでサーバーサイドにセッションを保持しているのかと思っていました。このセッションストアが KVS だったり ActiveRecord だったりするのかなと思っていたのですが・・・。DB にセッション情報を永続化して都度取得するようにすると重くなってしまうので、インメモリもしくは KVS あたりにセッション情報を保存するのかなと思っていました。
+
+上記の例では、**ユーザのID(普通は整数)** だけがセッションに入っています。アプリ側ではセッションから読み出した **ユーザのIDを使ってユーザをDBから取得** します。多くはいったん読み出したユーザのデータをコントローラのインスタンス変数に保持し、コントローラとビューの各所で使いまわします(慣用的に`current_user`というアクセサで取るようにつくります)。言い換えますと、「セッション情報に含む」と「セッション情報に含まれるキーから読み出したDB上のデータを、リクエストの間中メモリ上に保持すること」は違うということです。
+
+ちなみに、余程のことがなければリクエストごとにDBから検索してきてもそうそう速度へのインパクトはないかと思いますし、実際にそこで困ったことはありませんね。
+
+> 全て Cookie に保存する場合、ショッピングカートなどを実現しようと思ったらきっとサーバー側の永続化層にセッション情報を持たざるを得ない気がしますが(間違っていたらご指摘ください)、例えば良くあるユーザーのロール/権限などの情報はどうするのでしょうか?これも Cookie に保存するのが一般的なのでしょうか?
+
+サーバ側で読み出したユーザデータをつかって、ふつうにサーバ側でカートを実装することが多いですね。DBMSにするか揮発するKVSにするかなどの手段はともあれ、おっしゃるとおりサーバ側の何処かに永続化します。権限も、読みだしたユーザデータに紐づくようなものをまた権限テーブル的なところから読み出したりして判定します。
+
+> また、サーバー側で「現在アクセス中のユーザー」を取得せざるを得ないケースが多いかと思うのですが、session id と user の紐づけはどのように行うのでしょうか?user id を Cookie に保存するのはマズいですよね・・・?
+
+上記のように、セッション中(つまりcookie中)に保存したユーザIDを使って検索します。セッションcookieは改竄防止の署名がありますので、IDを保存してまずい理由はとくにありません。逆に言うと、見られてマズイ情報はセッションに入れません。ユーザ本人に見られてマズイ情報(改竄はされない)って意外と少ないです。
+
+### 1
+
+> ただ、これって https の場合になりすましを防ぐ方法になっていますが、そもそも https でなりすまし(というか Cookie の盗聴)されるケースってあるのでしょうか……?
+
+言い方がわかりづらかったかもしれません。あのページは、「httpとhttpsのどちらのページもあるサービスを提供している場合に、http側でクッキーが盗まれてもhttps側に被害を出さない」方法を説明しています。ですから、すべてをhttpsでくるんでしまえば盗聴、ひいてはなりすましは考えなくても良いでしょう(証明書の運用などに気をつけ、SSLを正しく使っている限り)。
+
+### 2, 3
+
+どこまで〜、はなかなか悩ましいですよね。ということで、盗聴やなりすまし対策については「すべてhttpsにしましょう」という構成にすることで話をつけています。すぐ上で書いたように、すべてhttpsであれば元回答にあるようなシナリオでのセッションハイジャックは対策ずみになります。
+
+### 4
+
+4であげられていた点も回答済みかと思いますが、いかがでしょうか。
+
+繰り返しになりますが、Railsでは
+
+1. セッションデータ
+2. セッションデータに入っている何らかのキーをもとにDBから引いてきてメモリに保持しアクション内で引き回すデータ
+
+は明確に区別されます。cookieに保存されるのは1.のデータで、これはユーザのIDや最終アクセス時刻など *4KB* にすら到底及ばないようなデータです。アプリケーション側では、そのセッションデータを元に2.のデータをロードし、実際の処理で使うのでした。権限やロールもユーザデータに含まれるキーなどを元に都度DBから読みだして行き、サーバ側での処理に用います。

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を すべて Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で4KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

1. Cookieが覗き見されたらどうする問題

そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!!

一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。素のhttpでパケットを盗聴されるケースも、アプリ側ではほとんどなにもできません。最近大手のサービスが軒並み常時httpsになっているのは、この辺の事情かと思います。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieにhttp only属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

4. について

いくつか論点がありますが、

Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。session[:user_id]的な識別子が欲しい場合request.env['Authorization']を適宜パースすればよさそうです。

また、もしも4KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合はRails session ActiveRecordStoreあたりで調べていただければ良いかと思います。


以下、追記への回答です

@ursm さんから指摘があって回答を変更しました。cookieサイズ(=通常のセッションサイズ)の上限は4KBでした。とても小さいですね。とはいえ、実用上は特に困らないというのは相変わらずです。

良く Rails で session[:user_id] みたいなコードを見るのでサーバーサイドにセッションを保持しているのかと思っていました。このセッションストアが KVS だったり ActiveRecord だったりするのかなと思っていたのですが・・・。DB にセッション情報を永続化して都度取得するようにすると重くなってしまうので、インメモリもしくは KVS あたりにセッション情報を保存するのかなと思っていました。

上記の例では、ユーザのID(普通は整数) だけがセッションに入っています。アプリ側ではセッションから読み出した ユーザのIDを使ってユーザをDBから取得 します。多くはいったん読み出したユーザのデータをコントローラのインスタンス変数に保持し、コントローラとビューの各所で使いまわします(慣用的にcurrent_userというアクセサで取るようにつくります)。言い換えますと、「セッション情報に含む」と「セッション情報に含まれるキーから読み出したDB上のデータを、リクエストの間中メモリ上に保持すること」は違うということです。

ちなみに、余程のことがなければリクエストごとにDBから検索してきてもそうそう速度へのインパクトはないかと思いますし、実際にそこで困ったことはありませんね。

全て Cookie に保存する場合、ショッピングカートなどを実現しようと思ったらきっとサーバー側の永続化層にセッション情報を持たざるを得ない気がしますが(間違っていたらご指摘ください)、例えば良くあるユーザーのロール/権限などの情報はどうするのでしょうか?これも Cookie に保存するのが一般的なのでしょうか?

サーバ側で読み出したユーザデータをつかって、ふつうにサーバ側でカートを実装することが多いですね。DBMSにするか揮発するKVSにするかなどの手段はともあれ、おっしゃるとおりサーバ側の何処かに永続化します。権限も、読みだしたユーザデータに紐づくようなものをまた権限テーブル的なところから読み出したりして判定します。

また、サーバー側で「現在アクセス中のユーザー」を取得せざるを得ないケースが多いかと思うのですが、session id と user の紐づけはどのように行うのでしょうか?user id を Cookie に保存するのはマズいですよね・・・?

上記のように、セッション中(つまりcookie中)に保存したユーザIDを使って検索します。セッションcookieは改竄防止の署名がありますので、IDを保存してまずい理由はとくにありません。逆に言うと、見られてマズイ情報はセッションに入れません。ユーザ本人に見られてマズイ情報(改竄はされない)って意外と少ないです。

1

ただ、これって https の場合になりすましを防ぐ方法になっていますが、そもそも https でなりすまし(というか Cookie の盗聴)されるケースってあるのでしょうか……?

言い方がわかりづらかったかもしれません。あのページは、「httpとhttpsのどちらのページもあるサービスを提供している場合に、http側でクッキーが盗まれてもhttps側に被害を出さない」方法を説明しています。ですから、すべてをhttpsでくるんでしまえば盗聴、ひいてはなりすましは考えなくても良いでしょう(証明書の運用などに気をつけ、SSLを正しく使っている限り)。

2, 3

どこまで〜、はなかなか悩ましいですよね。ということで、盗聴やなりすまし対策については「すべてhttpsにしましょう」という構成にすることで話をつけています。すぐ上で書いたように、すべてhttpsであれば元回答にあるようなシナリオでのセッションハイジャックは対策ずみになります。

4

4であげられていた点も回答済みかと思いますが、いかがでしょうか。

繰り返しになりますが、Railsでは

  1. セッションデータ
  2. セッションデータに入っている何らかのキーをもとにDBから引いてきてメモリに保持しアクション内で引き回すデータ

は明確に区別されます。cookieに保存されるのは1.のデータで、これはユーザのIDや最終アクセス時刻など 4KB にすら到底及ばないようなデータです。アプリケーション側では、そのセッションデータを元に2.のデータをロードし、実際の処理で使うのでした。権限やロールもユーザデータに含まれるキーなどを元に都度DBから読みだして行き、サーバ側での処理に用います。

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

> 実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を **すべて** Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で4KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

## 1. Cookieが覗き見されたらどうする問題

> そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!!

一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。素のhttpでパケットを盗聴されるケースも、アプリ側ではほとんどなにもできません。最近大手のサービスが軒並み常時httpsになっているのは、この辺の事情かと思います。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieに`http only`属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

## 2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

## 3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

## 4. について

いくつか論点がありますが、

> Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

> 少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。`session[:user_id]`的な識別子が欲しい場合`request.env['Authorization']`を適宜パースすればよさそうです。

また、もしも4KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合は`Rails session ActiveRecordStore`あたりで調べていただければ良いかと思います。

------------------

# 以下、追記への回答です

@ursm さんから指摘があって回答を変更しました。cookieサイズ(=通常のセッションサイズ)の上限は4KBでした。とても小さいですね。とはいえ、実用上は特に困らないというのは相変わらずです。

> 良く Rails で session[:user_id] みたいなコードを見るのでサーバーサイドにセッションを保持しているのかと思っていました。このセッションストアが KVS だったり ActiveRecord だったりするのかなと思っていたのですが・・・。DB にセッション情報を永続化して都度取得するようにすると重くなってしまうので、インメモリもしくは KVS あたりにセッション情報を保存するのかなと思っていました。

上記の例では、**ユーザのID(普通は整数)** だけがセッションに入っています。アプリ側ではセッションから読み出した **ユーザのIDを使ってユーザをDBから取得** します。多くはいったん読み出したユーザのデータをコントローラのインスタンス変数に保持し、コントローラとビューの各所で使いまわします(慣用的に`current_user`というアクセサで取るようにつくります)。言い換えますと、「セッション情報に含む」と「セッション情報に含まれるキーから読み出したDB上のデータを、リクエストの間中メモリ上に保持すること」は違うということです。

ちなみに、余程のことがなければリクエストごとにDBから検索してきてもそうそう速度へのインパクトはないかと思いますし、実際にそこで困ったことはありませんね。

> 全て Cookie に保存する場合、ショッピングカートなどを実現しようと思ったらきっとサーバー側の永続化層にセッション情報を持たざるを得ない気がしますが(間違っていたらご指摘ください)、例えば良くあるユーザーのロール/権限などの情報はどうするのでしょうか?これも Cookie に保存するのが一般的なのでしょうか?

サーバ側で読み出したユーザデータをつかって、ふつうにサーバ側でカートを実装することが多いですね。DBMSにするか揮発するKVSにするかなどの手段はともあれ、おっしゃるとおりサーバ側の何処かに永続化します。権限も、読みだしたユーザデータに紐づくようなものをまた権限テーブル的なところから読み出したりして判定します。

> また、サーバー側で「現在アクセス中のユーザー」を取得せざるを得ないケースが多いかと思うのですが、session id と user の紐づけはどのように行うのでしょうか?user id を Cookie に保存するのはマズいですよね・・・?

上記のように、セッション中(つまりcookie中)に保存したユーザIDを使って検索します。セッションcookieは改竄防止の署名がありますので、IDを保存してまずい理由はとくにありません。逆に言うと、見られてマズイ情報はセッションに入れません。ユーザ本人に見られてマズイ情報(改竄はされない)って意外と少ないです。

### 1

> ただ、これって https の場合になりすましを防ぐ方法になっていますが、そもそも https でなりすまし(というか Cookie の盗聴)されるケースってあるのでしょうか……?

言い方がわかりづらかったかもしれません。あのページは、「httpとhttpsのどちらのページもあるサービスを提供している場合に、http側でクッキーが盗まれてもhttps側に被害を出さない」方法を説明しています。ですから、すべてをhttpsでくるんでしまえば盗聴、ひいてはなりすましは考えなくても良いでしょう(証明書の運用などに気をつけ、SSLを正しく使っている限り)。

### 2, 3

どこまで〜、はなかなか悩ましいですよね。ということで、盗聴やなりすまし対策については「すべてhttpsにしましょう」という構成にすることで話をつけています。すぐ上で書いたように、すべてhttpsであれば元回答にあるようなシナリオでのセッションハイジャックは対策ずみになります。

### 4

4であげられていた点も回答済みかと思いますが、いかがでしょうか。

繰り返しになりますが、Railsでは

1. セッションデータ
2. セッションデータに入っている何らかのキーをもとにDBから引いてきてメモリに保持しアクション内で引き回すデータ

は明確に区別されます。cookieに保存されるのは1.のデータで、これはユーザのIDや最終アクセス時刻など *4KB* にすら到底及ばないようなデータです。アプリケーション側では、そのセッションデータを元に2.のデータをロードし、実際の処理で使うのでした。権限やロールもユーザデータに含まれるキーなどを元に都度DBから読みだして行き、サーバ側での処理に用います。

cookieサイズは4KBでした。

887
 
 BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。`session[:user_id]`的な識別子が欲しい場合`request.env['Authorization']`を適宜パースすればよさそうです。
 
-また、もしも64KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合は`Rails session ActiveRecordStore`あたりで調べていただければ良いかと思います。
+また、もしも4KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合は`Rails session ActiveRecordStore`あたりで調べていただければ良いかと思います。

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を すべて Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で4KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

1. Cookieが覗き見されたらどうする問題

そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!!

一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。素のhttpでパケットを盗聴されるケースも、アプリ側ではほとんどなにもできません。最近大手のサービスが軒並み常時httpsになっているのは、この辺の事情かと思います。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieにhttp only属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

4. について

いくつか論点がありますが、

Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。session[:user_id]的な識別子が欲しい場合request.env['Authorization']を適宜パースすればよさそうです。

また、もしも4KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合はRails session ActiveRecordStoreあたりで調べていただければ良いかと思います。

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

> 実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を **すべて** Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で4KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

## 1. Cookieが覗き見されたらどうする問題

> そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!!

一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。素のhttpでパケットを盗聴されるケースも、アプリ側ではほとんどなにもできません。最近大手のサービスが軒並み常時httpsになっているのは、この辺の事情かと思います。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieに`http only`属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

## 2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

## 3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

## 4. について

いくつか論点がありますが、

> Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

> 少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。`session[:user_id]`的な識別子が欲しい場合`request.env['Authorization']`を適宜パースすればよさそうです。

また、もしも4KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合は`Rails session ActiveRecordStore`あたりで調べていただければ良いかと思います。

一般的に Cookie には 64KB も入りません

996
 
 > 実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。
 
-こちらは誤解で、Railsは(デフォルトでは)セッション情報を **すべて** Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で64KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。
+こちらは誤解で、Railsは(デフォルトでは)セッション情報を **すべて** Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で4KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。
 
 ## 1. Cookieが覗き見されたらどうする問題
 

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を すべて Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で4KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

1. Cookieが覗き見されたらどうする問題

そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!!

一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。素のhttpでパケットを盗聴されるケースも、アプリ側ではほとんどなにもできません。最近大手のサービスが軒並み常時httpsになっているのは、この辺の事情かと思います。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieにhttp only属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

4. について

いくつか論点がありますが、

Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。session[:user_id]的な識別子が欲しい場合request.env['Authorization']を適宜パースすればよさそうです。

また、もしも64KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合はRails session ActiveRecordStoreあたりで調べていただければ良いかと思います。

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

> 実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を **すべて** Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で4KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

## 1. Cookieが覗き見されたらどうする問題

> そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!!

一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。素のhttpでパケットを盗聴されるケースも、アプリ側ではほとんどなにもできません。最近大手のサービスが軒並み常時httpsになっているのは、この辺の事情かと思います。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieに`http only`属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

## 2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

## 3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

## 4. について

いくつか論点がありますが、

> Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

> 少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。`session[:user_id]`的な識別子が欲しい場合`request.env['Authorization']`を適宜パースすればよさそうです。

また、もしも64KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合は`Rails session ActiveRecordStore`あたりで調べていただければ良いかと思います。

ブラウザのバグの他に、パケット盗聴でも当然httpのcookieは漏れるという話を追加

887
 
 > そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?
 
-乗っとり可能です!! 一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。
+乗っとり可能です!!
+
+一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。素のhttpでパケットを盗聴されるケースも、アプリ側ではほとんどなにもできません。最近大手のサービスが軒並み常時httpsになっているのは、この辺の事情かと思います。
 
 というのが前提だと思ってください。
 

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を すべて Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で64KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

1. Cookieが覗き見されたらどうする問題

そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!!

一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。素のhttpでパケットを盗聴されるケースも、アプリ側ではほとんどなにもできません。最近大手のサービスが軒並み常時httpsになっているのは、この辺の事情かと思います。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieにhttp only属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

4. について

いくつか論点がありますが、

Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。session[:user_id]的な識別子が欲しい場合request.env['Authorization']を適宜パースすればよさそうです。

また、もしも64KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合はRails session ActiveRecordStoreあたりで調べていただければ良いかと思います。

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

> 実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を **すべて** Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で64KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

## 1. Cookieが覗き見されたらどうする問題

> そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!!

一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。素のhttpでパケットを盗聴されるケースも、アプリ側ではほとんどなにもできません。最近大手のサービスが軒並み常時httpsになっているのは、この辺の事情かと思います。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieに`http only`属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

## 2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

## 3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

## 4. について

いくつか論点がありますが、

> Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

> 少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。`session[:user_id]`的な識別子が欲しい場合`request.env['Authorization']`を適宜パースすればよさそうです。

また、もしも64KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合は`Rails session ActiveRecordStore`あたりで調べていただければ良いかと思います。

回答を投稿

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を すべて Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で64KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

1. Cookieが覗き見されたらどうする問題

そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!! 一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieにhttp only属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

4. について

いくつか論点がありますが、

Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。session[:user_id]的な識別子が欲しい場合request.env['Authorization']を適宜パースすればよさそうです。

また、もしも64KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合はRails session ActiveRecordStoreあたりで調べていただければ良いかと思います。

こんにちは。Railsのセッション管理についての質問だと想定し、アプリの作りに依存しそうな部分はRails前提で回答します。

まずはじめに

> 実態としてはサーバーサイドに保持し、セッション ID は Cookie に保存しているものだと思っています(Rails の経験が殆ど無いので間違っていたらすみません)。

こちらは誤解で、Railsは(デフォルトでは)セッション情報を **すべて** Cookieに入れます。ですからたとえばRailsのセッション情報はシリアライズした上で64KBまでしか入れられませんが、それはそういうものだから設計を見なおすべき、というのがRails wayであるとされています。

## 1. Cookieが覗き見されたらどうする問題

> そうは言っても Cookie の値は HTTP リクエストに乗って送信されます。仮にこのリクエストを覗き見されてしまうとそのままセッションの乗っ取りが可能ですよね?

乗っとり可能です!! 一般論として、Webアプリで悪意ある第三者にCookieが盗まれたらヤバイです。けっこうどうしようもありません。だいたいはブラウザのバグです。Webアプリ側で盗まれないようにするのはほぼ不可能です。

というのが前提だと思ってください。

そのうえで、盗まれにくくしたり、盗まれても被害を減少させる手法はいくつかあります。

そのうちの1つがhttpsとhttpでは認証の仕方を変えるというものがあります。httpsでの通信の場合は別のhttpsでしか流れないCookie(Secure Cookie)の情報も参照して、一致している場合のみ有効なセッション情報とするという対応です。

けっこうややこしいですが、下記のRails Castの説明が詳しくていいと思います。

http://railscasts.com/episodes/356-dangers-of-session-hijacking?language=ja&view=asciicast

この場合は『httpではなりすまされても仕方ないが、httpsでは防ぎたい』という線引で、重要な操作はhttpsで行うことで実質の被害を減少させる手法ですね。

あとはCookieに`http only`属性を付けて悪意あるJSからのアクセスを防いだり、セッション中に短めのexpire時間を設定し、攻撃者に盗まれたCookieをすぐ無効化できるようにする、などがあげられます。

## 2. ログイン画面がhttpsなのは〜

おっしゃるとおり第三者の覗き見を避けるのと、送信先のサーバが間違いなくはてなであることを保証するためかと思います。

## 3. 業務アプリケーションのようにプライベートネットワーク内でしか動かない Web アプリケーションの場合

わたしはこのごろはだいたいの案件で、すべてのページをhttpsにしています。httpとhttps混在させるとかえって面倒(JSの生成元同一ポリシーなどとの絡みで)なので、基本はすべてhttpsの中に置き、どうしても必要な場合のみhttpのページを作っています。

サービス系だとSNS系メディアとの関係でhttpのページが必要になることは多いですが、業務だと逆にすべてhttps下で困ることはあまりないのではないでしょうか。

## 4. について

いくつか論点がありますが、

> Rails は Cookie およびサーバーサイドにセッション情報を保存していますが、REST 本来の意味ではこれは NG だと思っています。

上述のように、セッション情報はすべてCookieに入っています。当然ながら、Cookieも実体はHTTPリクエストヘッダであり、リクエストの一部です。

サーバサイドに保存しているリソースであるところのユーザのIDが入っていて、ユーザの実体はサーバサイドにあるじゃないかといわれるとそうなんですが、それがREST的にNGだとは思いませんがいかがでしょうか。

> 少なくとも Cookie は使うことになるのかなと思っています。Cookie を使わない方法もあるのでしょうか?Web アプリで BASIC 認証や Digest 認証は使えませんよね?

BASIC認証やDigest認証も使えます。けっこう簡単です。あのあまり見栄えの良くないブラウザダイアログを許容するのであれば、ごく少数のユーザ向け認証はhttps+BASIC認証でやったりもします。`session[:user_id]`的な識別子が欲しい場合`request.env['Authorization']`を適宜パースすればよさそうです。

また、もしも64KB以上のデータをセッションに入れたい場合は、セッション情報をDBに入れてCookieにはセッションIDだけを保存することも可能です。その場合は`Rails session ActiveRecordStore`あたりで調べていただければ良いかと思います。