カテゴリー
PHP Security Security

セッションID管理は結局どうすれば良いのか?

脆弱性やセキュリティ対策について技術的な話ばかりしていたので「それで結局PHPのセッション管理どうすれば良いの?」と思われた方も多いと思います。簡単にまとめます。漏れや追記した方が良い事などがあったらご指摘ください。

カテゴリー
Security

セッションアダプション脆弱性がないセッション管理が必要な理由

徳丸さんから「ブログ読みました。サンプルも動かしました。問題は分かるのですが、セッションアダプションがないPHPだと、何が改善されるのかが分かりません。教えて下さい 」とあったのでツイッターで返信するには少し長いのでこちらに書きます。まだ直していない脆弱性を詳しく解説するのはあまりよくないのですが、今なら影響を受けるアプリはほぼないと思うので構わないでしょう。

まず前提として、Webサーバと同様にJavascriptからもクッキーが設定できます。Javascriptインジェクションに脆弱なコードがサイトに1つでもあると、サイト上のセッションアダプション脆弱性をもつアプリへの攻撃が可能になります。この攻撃を緩和する対策もありますが、それはそれ、これはこれなので省略します。

セッションアダプションに脆弱なセッション管理機構で困る代表的なケースは以下の通りでしょう。

  1. ログイン時にsession_regenerate_idを呼んでない
  2. 自動ログインなど通常のセッション用以外でsession_regenerate_idを呼んでいない
  3. session_regenerate_idを呼んでいても、途中で保存している
  4. session_regenerate_idを呼んでいても、途中で実行パスが変えられる
カテゴリー
Security

PHPのセッションアダプション脆弱性は修正して当然の脆弱性

PHPのセッションアダプション脆弱性がどのように影響するのか、広く誤解されているようです。セキュリティ専門家でも正しく理解していないので、一部のPHP開発者が正しく理解しなかったのは仕方ないのかも知れません。

Webセキュリティの第一人者の一人である徳丸氏は「PHPのセッションアダプション脆弱性は脅威ではない」と書いていますが、いろいろ間違いです。私は2005年頃から現在まで様々な機会に問題であると何度も繰り返し説明しており、しばらくすれば間違いに自分で気付くのでは?と思っていたので特に反論していませんでした。しかし、まだ気づかれていないようなので、幾つかある攻撃パターンのうち解りやすい例を1つだけ紹介しておきます。

カテゴリー
Computer Development PHP Security Programming Secure Coding

セッションのクッキーを設定する場合のベストプラクティス

HTTPセッションは通常クッキーを利用して行います。クッキーを利用したセッションの場合、お薦めする設定は以下の通りです。

  1. ドメイン名は指定しない
  2. パスはルート(/)を指定する
  3. セッション管理用のクッキーはセッションクッキー(有効期間0)にする
  4. httponly属性を付ける
  5. 可能な場合は必ずsecure属性をつける
  6. 複数アプリケーションを利用する場合はsession.nameまたはsession_name()でセッションクッキー名で指定する (アプリケーションの固有名デフォルトで設定し、設定項目として変更できるようにする)
カテゴリー
Programming

Session Adoptionが攻撃に有用な実例

PHP:既知のセキュリティ脆弱性 – Session AdoptionでWebmailアプリケーションであるSquirrelMailとRoundCubeがこの攻撃に脆弱であることを紹介しました。

タイミング良く(?)同じくPHPベースのWebmailアプリであるIMPにクロスサイトスクリプティング脆弱性が発見され修正されました。(IMP-4.3.3未満/IMP-4.2.2未満)

試しに、ソースコードをチェックしてみました。

カテゴリー
PHP Security Programming

ログイン後にsession_regenerate_id()を実行するだけで十分か?

忙し過ぎてタイムリーにブログが書けないです。最近セッション管理の問題が一部で話題になっていました。そこの中に以下のような議論がありました。

ログイン後にsession_regenerate_id()を実行すれば外部からのセッションIDを受け入れても安全

確かにログイン後のセッションIDは本来セッションIDが持つべき属性

  •  一意な値であること
  • 第三者に予測不可能であること

を持っています。

しかし、ログイン後にセッションIDを再生成するだけでは不十分な場合は2つ直ぐに思いつきます。

– CSRF(XSRF)防御にセッションID(だけ)を利用している場合
– 外部に出力したデータの改ざん防止にセッションID(だけ)を利用している場合

これらの仕組みはログイン後にのみ利用する機能ではありません。フォーム送信は認証無しで行うことは多いです。ウィザード型の入力フォーム(検証済みの前のページの入力値を次ページに保存する方法が最も柔軟な処理方法)も認証前に使用されます。

私はCSRF(XSRF)防御にはフォームに予測不可な一意なIDを割り当てる方式を、検証済みデータの改ざん防止にはセッションID+マジック文字列(予測できない秘密の文字列)を利用しています。CSRF(XSRF)対策には影響ないですし、セッションIDを利用してセキュリティを維持する仕組みであっても必ずマジック文字列を使用しているので危険な状態にはなりません。しかし、全てのアプリケーションがこのような対策を取っているとは思えないので外部からのセッションIDを受け付けない厳格なセッションID管理を導入するのはセキュリティ上意味があります。

ほとんどのアプリケーションはログイン後にsession_regenerat_id()を実行するだけで十分な安全性を確保することが可能ですが一部のアプリケーションはそれでは不十分であることは知っておいたほうが良いと思います。

追記:2001年からウィザード型フォームで前のページのデータを安全に保存するため等に利用できる関数をZendのコードギャラリに載せています。ウィザード型フォームはこのような関数を使用し検証済みの値のメッセージダイジェストを取っておけと繰り返し入力値を検証する必要性がなくなります。

カテゴリー
Computer Development PHP Security Programming Secure Coding Security

解答:まちがった自動ログイン処理

問題:まちがった自動ログイン処理の解答です。このブログエントリは最近作られたアプリケーションでは「問題」にしたような実装は行われていないはず、と期待していたのですがあっさり期待を破られたのでブログに書きました。このブログの方が詳しく書いていますけが「Webアプリセキュリティ対策入門」にも正しい自動ログイン処理を書いています。

参考:自動ログイン以外に2要素認証も重要です。「今すぐできる、Webサイトへの2要素認証導入」こちらもどうぞ。HMACを利用した安全なAPIキーの送受信も参考にどうぞ。