セッションやCookie、認証の関係の基礎の基礎

セッションや認証って難しいですね。
他のテーマ?に比べて、参考資料がウェブ上に少ない。
こればかりは本を買わないといけないかと頭を悩ましています。



はじめに

出来れば個人情報は一切預かりたくないと思っています。
なぜならそれにみあうスキルがないから。
リスクが高いのに、預かる意味がないし。


ただ会員管理というか、利用者の一意性を確保する必要がある場合、メールアドレスだけは預からざるをえません。
そうするとセッションや認証も気合いをいれて使わないと、あっという間にメールアドレス流出に至って大惨事になるわけです。ぐむむ。


できれば、既存の物を利用したいのですが、ログインはソースを見られてしまうとセキュリティ的にも問題があるのでなかなか配布していないようです
PEAR::Authになっちゃうと、中で何やってるかわからずに使ってしまいそうで、より危険だし。


いつものごとく自分で書いてみて、動作させて、理解した上で、あれこれライブラリの類の検討をすることにしました。
そこで、セッションや認証の基礎の基礎を自分用にメモしておきます。


入り口

SledgeというPerlフレームワークを説明する前置きですが、改めてセッションとは何かという頭の整理をするのにわかりやすいです。


セッションとは(ThinkIT)
 http://www.thinkit.co.jp/free/tech/9/2/1.html


つまり

・HTTPは、ステートレスなプロトコルである
・ステートレスゆえに「一意性を保証するキー」(「リクエストとその"主"を結びつけるためのしくみ」)が必要になる。
・その仕組みがセッションIDである。
・セッションIDの受け渡しはCookie等で行う。


そもそもセッションには、任意の情報を用いることが出来ます。
Cookieの場合、クライアントにはCookie nameCookie valueCookieを特定するための値)が記録されます。
一方サーバに保存されるセッションファイルには、指定した任意の情報が記録されます。


クライアントは当該サーバに関するCookie nameCookie valueを自動送出します。
サービス側は、受け取ったCookie nameCookie valueをセッションIDとして、セッションファイルに保存されている上記「指定した任意の情報」を読み出すわけです(セッションIDを他で受渡す方法ももちろんあります)


しかし
(1)Cookie valueはユーザー等が直接操作することも可能。
(2)セキュリティホール等で他人に読まれた際に情報流出が生じる危険性。
したがってCookieに生の情報を保存するのは妥当でない。


そこでセッションIDはランダムな文字列でなければならない。
セッションID以外のセンシティブ情報はセッションとしては扱わない。
「類推されにくい一意な情報の小片のみ」用いることになるのだと思います(多分)



http://74.125.153.132/search?q=cache:http://dev.ishinao.net/archives/000021.html[:title=おまけ: 認証状態を保存する方法] (dev.ishinao.net)
http://74.125.153.132/search?q=cache:http://dev.ishinao.net/archives/000021.html


6. Webアプリケーションのセキュア化における留意点(IPA)
 http://www.ipa.go.jp/security/awareness/administrator/secure-web/chap6/6_index.html


セッションIDの生成

セッションを用いて一意性を確認するということは、セッションIDの送出はIDとパスワードの組み合わせの送信に近い意味を持ちます。
したがって、セッションIDはIDとパスワードの組み合わせ同様の管理を要求されます。


つまり、推測や総あたり等によってわかってしまうようなものであってはいけません。
また通信経路上での傍受に対処する必要があります(つまり通常SSLが要求されるでしょう)
さらにはpathにセッションIDを付加すると、HTTPリファラに載せて、外部のサイトにセッションIDを開示してしまいます(だからpathでのセッションID受渡しに比べcookieが望ましいのですね)


以上を前提として、具体例にいきます。


クッキーとセッション管理
 http://oku.edu.mie-u.ac.jp/~okumura/php/session.php


session_start()で、PHPSESSIDというセッション名のセッションIDをランダムな文字列自動的に生成し、Cookieとしてクライアント側に送ります。


あとはCookieについてパラメータをあれこれ付与してセキュリティを確保することになります。
以下の記事には、(1)ログイン成功後にはじめてセッションIDを発行するか、ログイン成功後にsession_regenerate_id()でセッションIDを変更するSession Fixation対策が必要であること、(2)共用サーバでのセッションの保存場所等必要不可欠な設定事項が数多く書かれています。


PHP - session利用のまとめ(1:n - DETELU Blog)
 http://www.detelu.com/blog/?p=231


その他、関係記事。


セッションIDが利用できる範囲を制限する(技術評論社)
 http://gihyo.jp/dev/serial/01/php-security/extra/001203


PHP と Web アプリケーションのセキュリティについてのメモ - PHP でセッション変数、Cookie を使用する際のセキュリティ対策について
 http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_security.html#PHP_Session


携帯電話向けWebアプリのセッション管理はどうなっているか
 http://d.hatena.ne.jp/ockeghem/20090714/p1


クロスサイトリクエストフォージェリ(CSRF)の正しい対策方法(高木浩光@自宅の日記)
 http://takagi-hiromitsu.jp/diary/20050427.html


えび日記: CSRFの説明に追記 (おおいわのこめんと)
 http://www.oiwa.jp/~yutaka/tdiary/20060330.html



CSRFは、「http://takagi-hiromitsu.jp/diary/20050427.html:title=Webアプリケーションに対して何らかの恒久的な データ変更を発生させるアクセスとなるページ]」について、定まった手順でアクセスできてしまう問題なんですね。だからトークン等で前のページから次のページへの遷移を確認する必要があるということか。ぼくはまちちゃん!とようやく結びつきました。
一連のページの流れで、認証をかけてないから途中の各ページがあるとそこにダイレクトアクセスされるとマズイよ、という話かと勘違いしてました(そんなマヌケはいない)。


結論

セッションやCookie、認証の関係ってムズカシイデスネ……。
しかし、色々な記事を読みながら書いているうちになんとなくイメージがつかめるようになりました。


セッション変数がサーバに保管されるもの(セッションファイル)で、クライアント側が持つただ一つだけセッション情報として持つセッションIDを使って紐つける、というのがピンとつかめるまでに時間がかかりました(ブラウザのクッキー情報みればわかるんですけどね)。
下の記事を読んでようやく確信できました。


第4回 サーバー側で管理する「セッション変数」に要注意(IT Pro)
 http://itpro.nikkeibp.co.jp/article/COLUMN/20080221/294390/



とりあえずそのイメージの下実際に手を動かしてみて、間違っていたら直します、はい。


10日で覚えるPHPのキソ 第 10 回 セッション(SESSION)(バシャログ。)
 http://c-brains.jp/blog/wsg/08/05/22-193020.php