タグ: セッション管理

PHP用のCookieセッションセーブハンドラー

JWTが凄い使われ方をしているようなので、可能な限りマシなCookieベースのセッションセーブハンドラーを書きました。メリットは

  • サーバー側のリソース(DBやファイルなど)を使わないので簡単にスケールする

ことにあります。

しかし、Cookieの保存は大きく分けて3つの問題があります。

  1. ネットワークが不安定だとデータが失われる場合がある(ネットワーク接続の問題)
  2. ロックがないのでデータが失われる場合がある(サーバー側の問題)
  3. 更新のタイミングによりデータが失われる場合がある(クライアント側の問題)

※ この問題はこのCookieを利用したセーブハンドラの問題ではなく、クッキー等のクライアント側にセッションデータを持たせるセッション管理の仕組み全般に存在します。

このハンドラーはデータ改ざんを検出するようになっており、Cookieの問題により改ざん攻撃と誤検出する可能性があります。

1、2は一般に広く認知されている問題でしょう。この場合はほぼ攻撃と誤検出されないと思われます。攻撃ではないのに攻撃と誤検出するのはほぼ3のケースだと考えられます。壊れ方によっては3ケースでも攻撃とは検出せず、仕様として単純にクッキーをリセットする場合もあります。タイミングによるデータ損失が100%攻撃と誤検出されるのではありません。

調べたのはしばらく前になりますが、タイミングによって失われるケースも完全に無視してよい程度ではありませんでした。これはブラウザのクッキー保存の実装コードの問題と考えられます。初期のバージョンはこの問題に対する緩和対策をしたコードにしていました。今は対タンパー性を上げる為にほぼ完全にバリデーションするコードになっています。(詳しくはコメント欄を参照)

どちらも一長一短で何とも言えないです。更新タイミングによるデータ損失が、どのブラウザで起きるのか、どのような使い方をすると起きるのか、どの程度あるのか、分らないので攻撃と誤検出するケースがある場合には教えていただけると助かります。※

※ 現コードはHMACで使用するクッキーをバリデーションしているので、更新タイミングによるデータ損失があると攻撃と誤検出します。きっちり正しく動作するコード ≠ きっちり厳格にバリデーションするコード、となる数少ないタイプのコードになります。ブラウザがRDBMSのトランザクションのように保存すれば済む話ですが。

もっと読む

PHPのheader関数とheaders_remove関数の注意点

PHPのheader関数とheader_remove関数の注意点です。あまり使わないと思いますが、Set-Cookieヘッダーや他のヘッダーで注意しないと問題になります。普段はsetcookie関数でクッキーを設定していてたまたまheader関数でクッキーを設定した、という場合にheader関数とsetcookie関数の仕様の違いにより、思ってもいない結果になります。

もっと読む

間違いだらけのHTTPセッション管理とその対策

HTTPセッション管理はWebセキュリティの中核と言える機能です。Webセキュリティの中核であるHTTPセッション管理に設計上のバグがある事は少なくありません。今回のエントリはPHP Webアプリ開発者ではなく、主にWebフレームワーク側の開発者、つまりPHP本体の方に間違いがあるという話しです。Webアプリ開発者の回避策も紹介します。

まずセキュリティの基本として「入力のバリデーションを行い、正当な入力のみを受け入れる」があります。しかし、PHPに限らず多くのセッション管理機構は当たり前の「入力のバリデーションを行い、正当な入力のみを受け入れる」を行っていません。セッションIDの再生成(リセット)も不完全な物が多いと思います。

参考:

もっと読む

Sessionアダプション脆弱性の修正

やっとPHPのセッションアダプション脆弱性を修正するパッチとプルリクエストを作りました。議論は済んでいるのでパッチを検証、調整してマージするだけです。

PHPに限らず、未初期化のセッションIDを正規のセッションIDとして受け入れてしまうセッション管理機構があります。(Javaとか)

サイトで稼働している全てのアプリが正しいセッション管理(ログイン後にセッションID作り直す。ログオフで廃棄。一定時間経過後、セッションIDを再生成)を実行していれば良いのですが、共有環境や複数のアプリが使われる事が多いPHPでは特にリスクが高くなっています。

未初期化のセッションIDを受け入れてしまうセッション管理機構は脆弱だと言って良いと考えています。セキュリティのベストプラクティスには確立されたセキュリティ手法(ベストプラクティス)はそのまま使うべき、というプラクティスがあります。つまり、信頼できるフレームワークのセッション管理機構をそのまま使いなさい、がベストプラクティスという事です。しかし、フレームワークとしてURLへのセッションID埋め込みをサポートしているのに、簡単に直せるセッションアダプションを修正しないフレームワークは到底「ベストプラクティスを実装している」と言える状態ではないと考えています。

セッションアダプション脆弱性についてはPHPのWiki(英語のみ)に書いています。詳しくは以下のWikiを参照してください。

もっと読む

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

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

もっと読む

セッションアダプションとセッションフィクセイションとセッションハイジャックの違いとは

徳丸さんがセッションアダプションをなくしても、セッションハイジャックが出来るのでsession_regenerate_id(true) (trueを付けると古いセッションデータは削除される)をしなければならないという記事を書かれています。

セッションアダプションがなくてもセッションフィクセイション攻撃は可能

http://tumblr.tokumaru.org/post/37676352092/session-adoption-and-session-fixation

まず結論を書きます。徳丸さんが「セッションフィクセイション攻撃は可能」と言われているのは間違いです。正しくは「セッションハイジャックが可能」です。

この議論は別々の異なる脆弱性を一緒にした議論で正しい議論とは言えません。セッションアダプション、セッションフィクセイション、セッションハイジャックとはどのような脆弱性なのか整理して議論する必要があります。

もっと読む

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

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

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

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

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

もっと読む

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

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

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

もっと読む

PHPのセッションアダプション脆弱性克服への道のり

PHP Advent Calender用のエントリです。

PHPのセッション管理は非常に簡単です。セッションをsession_start()で開始して$_SESSION配列を使うだけです。便利で簡単なセッションモジュールですがセッションアダプションに脆弱であるため、一般に言われてる「ログインする時にはsession_regenerate_id()を呼ぶ」コーディングではセッションアダプションに脆弱になってしまいます。

まずは危険性と対策を紹介します。 もっと読む

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

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

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

もっと読む

PHPのSession Adoptionを修正するパッチ

パッチのテストのお願いです。

PHPerの長年の悩みの種であるセッションアダプションを修正するパッチをPHPに取り込めそうです。PHPのsubversionレポジトリのtrunkまたはPHP 5.4で利用できます。テストが終わったらPHPのレポジトリにコミットする予定です。(テスト期間は2011/11/22まで)

パッチ

少し古いですがパッチの解説

セッションアダプション関連のブログエントリ

パッチに何か問題があったらご連絡頂けると助かります。問題なかったよ、も大歓迎です。

ツイッターの方がレスポンスは良いです。

メールご連絡頂いても構いません。ブログのコメントととして送信する場合はエラーメッセージを無視して送信してください。モデレーションが必要なコメントとして送信できます。

思い起こせばセッションアダプション脆弱性の修正は最初の提案から6年以上経っています。セッションアダプションとブラウザの仕様に関する理解を得られず今まで修正されてきませんでした。しかし、今回は修正できそうです。SQLインジェクション対策や入力のバリデーション処理もそうですが、正しいものは正しい。主張し続ければ時間はかかっても必ず正しい方が認められるのが世の中です。

今度こそPHPのアキレス腱であるセッションアダプション脆弱性を修正しましょう!

テストが可能な方は是非テストして頂けるよう、よろしくお願いします!

PHPセッションアダプションをスクリプト側で修正する方法

PHPのスクリプトを使ってアダプティブなPHPセッションをアダプティブにしない方法を紹介します。

このブログで紹介していたかどうか覚えていないですが、セッションアダプション対策としてsession_regenerate_id()が導入された時に議論・紹介されているので知っている方も多いと思います。(というより、PHPerの常識ですよね?)

まずはセッションアダプションの原理と対策の復習をしておきます。 もっと読む

PHPのSession Adoption脆弱性

PHPのセッションモジュールはセッションアダプションに脆弱なのですが、開発者の理解が得られず何年間も放置されています。

セッションアダプション脆弱性: 未初期化のセッションIDを受け入れてセッションを確立する脆弱性。

PHPのセッションIDはデフォルトでドメイン指定無し、パスは/に設定されています。専用サイトならこれであまり困ることは無いのですが、複数のアプリケーションやユーザが利用するようなサイトでは問題になります。

例えば、Chromeはパスよりドメインが優先されるのでドメインを利用したセッションIDの固定化などが起きます。IEではドメインよりパスが優先されるのでパスを利用したセッションIDの固定化などが起きます。

session_regenerate_id()を使えばOK、と考えている人も多いようですが既に設定済みのクッキーのうちどれが優先されてしまうか?が問題であるためsession_regenerate_id()を利用してもセッションIDは変わりません。優先されないクッキーを設定しても意味がないからです。

対策としては、すべてのドメイン、パスのセッションIDと同じクッキー名のクッキーを削除(空のクッキーを設定すると削除)する事ですがあまり多くの人がやっているとは思えません。根本的な解決策は「厳格なセッション管理」を行うことです。未初期化のセッションIDは受け入れないようにすれば完璧です。

セッションIDの固定化が可能な状況では、セッションアダプションに脆弱な場合はセッションを盗まれますが、厳格なセッション管理ならセッションIDを毎回振り直そうとする事になり、セッションは盗まれません。つまり、セッションが盗まれる代わりに「ログインできない」というDoS攻撃になります。セッションを盗まれるより、DoSの方が比べる必要がないくらいマシです。「ログインできない!」というユーザが居たら「ブラウザのクッキーを削除してください」と対応すれば良いだけです。

数年前にそろそろ直したら?とsecurity@php.netにメールしたのですが、開発者の問題だと勘違いしていて修正されませんでした。今日、またphp-internal@list.php.net internals@lists.php.net に再度メールをしておきました。さて、今回はどうなることでしょう?

Session Adoptionが攻撃に有用な実例

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

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

試しに、ソースコードをチェックしてみました。
もっと読む