3.1 HTTPとセッション管理
クッキーによるセッション管理
アプリケーションデータを保持する目的でクッキーに直接、値を入れることはあまり行われません。その理由は①クッキーに保持できる値の個数や文字長に制限がある。【 クッキー制約 ： クッキー１個当たり４ｋバイト、１Webサーバで２０個、１ブラウザで３００個 】②クッキーの値は利用者本人には参照、変更できるので、秘密情報の格納には向かない。
クッキーには「キー番号」としてのセッションIDを格納し、実際の値はサーバ側で管理するのが一般的です。
※ 昔は、Webブラウジングをすると利用者が知らないうちに、自動的に蓄積されていくクッキーの有害論があったが、現在は開発メーカとユーザ側間での歩み寄りの結果、セッション管理リスクの常識としては、「クッキーを使用する」のが最も安全になっている。

セッションIDの脆弱性 （セッションハイジャックなどを引き起こす）①セッションIDは推測できてはいけない（連番や社員番号などは避けて、疑似乱数生成器を使用する。セッション管理機能は自作しない。メジャーな開発ツールの提供するセッション管理機能を使用する。）②セッションIDは盗み出されないように厳重に管理する (XSS、HTTPヘッダ・インジェクション、Refererの悪用などから防御 → Webアプリに必要な脆弱性対策を作り込む必要がある )③セッションIDは強制されてはいけない （セッションフィクセーションから防御）

Refererの脆弱性
・セッション管理をするためには、Cookie、hiddenパラメータの他に、URL埋め込みのセッションIDが使えるが、情報漏洩の危険性が高い。
・ホームページにユーザのために用意されている機能に、外部サイトへのリンクがあったり、リンクを利用者が作成できる場合には、情報漏洩の危険性が高まる。
※ 利用者がセッションID付きのURLを自らSNSなどに投稿したり、何らかのきっかけでセッションID付きのURLが検索サイトに登録され、情報漏洩事故となった事例があります

セッションフィクセーション （セッションIDの固定化攻撃）※ セッションアダプション → 未知のセッションIDを受け付ける （PHPやASP.NETにある脆弱性）
PHP５．５．４以降では、「session.use_strict_mode = 1」を指定すると解消される （php.ini）
・認証前にセッション変数を使用している場合に、セッションフィクセーションを受ける場合がある・クッキーのみにセッションIDを保存する場合でも、セッションフィクセーションを受ける場合がある♠♠♠ クッキーモンスターバグ、XSS脆弱性、HTTPヘッダインジェクション脆弱性によって、中間者攻撃によるクッキー改竄攻撃は防ぐ方法がない ♠♠♠（HTTPでクッキーを設定すれば、そのクッキーはHTTPSでも有効になります。サイトがＨＴＴＰＳであっても、クッキー改変の可能性があるということです。）【対策】
セッションIDの固定化攻撃されることは許容し、攻撃を受けても、セッションハイジャックは防ぐように対策を行う①認証後にセッションIDを変更する(認証前にはセッション変数に秘密情報を保存しない)②ログイン時にトークンを生成し、クッキーとセッション変数の両方に記録し、認証確認時に比較（トークンが外部に出力されるのはログイン時のクッキー生成時のみなので、トークンを攻撃者が知る手段はありません）③セッション管理機構を自作しない

クッキーの属性対応
ＤｏｍａｉｎPathExpires
ＳｅｃｕｒｅＨｔｔｐＯｎｌｙ

ブラウザがクッキー値を送信するサーバのドメインを設定する（複数のサーバを介して、情報発信している場合など）→ 指定しない状態がもっとも安全
デフォルトは「path=/」。デレクトリを指定しても安全性に影響はない。（オリジンポリシーはホスト単位で、デレクトリ単位ではないから）→ 指定しない状態がもっとも安全設定しないとブラウザ終了でクッキー削除される。設定するとブラウザ終了後も認証状態が継続することになる。
→ 指定しない状態がもっとも安全
ＨＴＴＰＳの場合のみクッキーを送信→ 指定する方が普通は良い
ＪａｖａＳｃｒｉｐｔからのアクセスを禁止→ 指定する方が普通は良い

PHPのセッションID生成の安全性強化 （PHP-5.4.0からのデフォルト値）
php.ini[Session];; entropy_file は Windowsでは設定不要
session.entropy_file = /dev/urandom
session.entropy_length = 32

PHPのセッションIDがURL埋め込みになる条件
php.ini のセッションID設定項目
項目

session.use_cookies
session.use_only_cookies
session.use_trans_sid

デフォルト
説明
セッションの保存にCookieを使用する
有効（On）
セッションの保存にCookieのみを使用する有効（On）
URLにセッションIDを自動埋め込みする 無効（Off）

session.use_cookies と session.use_only_cookies
セッションIDの保存場所
セッションの保存にCookieのみを使用する
cookieが使えるときはcookieに、使えないときはURL埋め込み
無意味な組み合わせセッションIDを常にURL埋め込みにする「.user.ini」（デレクトリ毎のカスタマイズ設定ファイル）
セッションIDをURL埋め込みにする

session.use_cookies=Off
session.use_only_cookies=Off
session.use_trans_sid=On

session.use_cookies
OnOn
Off
Off

session.use_only_cookies
OnOffOnOff3.1 HTTPとセッション管理【サーバ：index.html】

【ブラウザ】

【サーバ： 31/index.html】【ブラウザ→サーバ： リクエスト 31/index.html → レスポンス 】

31-001:現在時刻【ブラウザ】【サーバ： 31/31-001.php 】

【ブラウザ→サーバ： リクエスト 31/31-001.php → レスポンス 】【ブラウザ】

31-002:入力-確認-登録【ブラウザ】【サーバ： 31/31-002.php 】

【ブラウザ→サーバ： リクエスト 31/31-002.php → レスポンス 】

【ブラウザ】<input>タグに入力した内容が、POSTメソッドで、サーバに送られます。

【サーバ： 31/31-003.php 】

ブラウザで入力した<input>タブの内容を、$_POSTで受け取って、変数に保存しています。

変数の内容について、htmlspecialchars関数で、サーバに危険な影響を及ぼさないようにエスケープ処理をしています。

【ブラウザ→サーバ： リクエスト 31/31-003.php → レスポンス 】

【ブラウザ】【サーバ： 31/31-004.php 】

【ブラウザ→サーバ： リクエスト 31/31-004.php → レスポンス 】

ブラウザで入力した<input>タブの内容が、パーセントエンコーディングされた形でメッセージボディ【ブラウザ】

hiddenパラメータの書き換え【ブラウザ】

ブレークポイントをセットブレークポイントをセッ【ブラウザ】

ブラウザから登録内容を送信【ブラウザ→サーバ： リクエスト 31/31-004.php → レスポンス 】

ブラウザからサーバに送られる
hiddenパラメータが表示される

ブラウザ利用者がOWASP ZAPなどのツールを使えば、hiddenパラメーブレークを開放する【ブラウザ】
hiddenパラメータのメリット
hiddenパラメータは利用者自身からは書き換え可能であるが、情報漏洩や第3者からの書き換えに関しては堅牢です。
クッキーやセッション変数は、セッションIDの固定化攻撃に弱い欠点があります。クッキーモンスターバグの影響で、セッション変数の漏洩に対する具体的な対策がありません。
利用者に書き換えられては困る認証や認可に関する情報はセッション変数に保存すべきだが、それ以外の特にログイン前の情報はhiddenパラメータが安全です。

31-010:Basic認証の実験【サーバ： 31/31-010.php 】

【ブラウザ】

【ブラウザ→サーバ（初期）： リクエスト 31/31-010.php → レスポンス 】（認証OKの場合）【ブラウザ】

【ブラウザ→サーバ（OK）： リクエスト 31/31-010.php → レスポンス 】

（認証NGの場合）【ブラウザ】

ユーザ、パスワードの認証に失敗すると【ブラウザ→サーバ（NG）： リクエスト 31/31-010.php → レスポンス 】

31-020:クッキーによるセッション管理【ブラウザ】【サーバ： 31/31-020.php 】

サーバとクライアント間で、セッション情報をやり取りします。
（具体的には、 session_start(); を実行します）

【ブラウザ→サーバ： リクエスト 31/31-020.php → レスポンス 】

サーバからクライアントに、Set-cookieでクッキーを送信しています【ブラウザ】

【サーバ： 31/31-021.php 】

サーバとクライアント間で、セッション情報をやり取りします。
（具体的には、 session_start(); を実行します）
ID,Passwordチェックの結果、問題がない場合に、$_SESSION に ID をセットしている。

【ブラウザ→サーバ： リクエスト 31/31-021.php → レスポンス 】

クライアントからサーバに、Cookie でクッキー値を送信しています【ブラウザ】

【サーバ： 31/31-022.php 】

変数の内容について、htmlspecialchars関数で、サーバに危険な影響を及ぼさないようにエスケープ処理をしています。

【ブラウザ→サーバ： リクエスト 31/31-022.php → レスポンス 】

【ブラウザ】