なぜPHPアプリにセキュリティホールが多いのか?

第46回 セキュリティ対策を考える上で欠かせないコンテクスト

この記事を読むのに必要な時間:およそ 9 分

原理・原則のセキュリティ対策

セキュリティ対策は多くのコンテクストに対応した対策であるほうが好ましいです。多くのコンテクストに対応するためには,セキュリティ対策の原理や原則を定義し,それを適用し,必要な場合には例外や補足を定義するほうが解りやすい場合が多いです。

セキュリティ対策で最も重要な対策は入力時と出力時の対策です。例えば,整形テキスト出力で脆弱性が発生する原理とセキュリティ対策の原則は以下の通りです。

出力時にセキュリティ脆弱性が発生する原理
  • 出力を受け入れるプログラムの入力仕様に従ったデータを出力しないため,出力先のプログラムが誤作動を起こす
出力時のセキュリティ対策の原則
  • エスケープ可能なパラメータはすべてエスケープ処理する
  • ヘルパー関数などが利用できる場合は利用する
  • エスケープもヘルパー関数も利用できない場合はバリデーションする
補足
  • 出力先の入力仕様,エスケープ仕様,ヘルパー関数などの仕様を正しく把握すること。出力先の入力仕様には最大データ長,文字エンコーディングの取り扱い,入力のタイミング※9などが含まれることに注意する。

この原則はほとんどの出力先に利用可能です。SQLインジェクション対策はもちろんJavaScriptインジェクション対策やXMLインジェクション対策などにも適用できます。

原理・原則だけでは具体的に特定のコンテクストに対してどのようなセキュリティ対策を行えばよいのかあまり明確ではありません。しかし,脆弱性の原理とセキュリティ対策の原則を説明した上で特定のコンテクストに対応したセキュリティ対策例を解説すると,ほかのコンテクストにおいても漏れのないセキュリティ対策実施の手助けになるでしょう。

幅広いコンテクストに対応できるのが原理・原則に基づくセキュリティ対策ですが,それだけでは具体性に欠けるところがこのアプローチの欠点です。

IPAの安全なSQLの呼び出し方を修正するなら,JDBC型のAPIの解説の次に,エスケープとバリデーションによるセキュリティ対策を追記します。こうすれば,必要なセキュリティ対策の漏れもなくなり,APIを独自実装している場合の確認も行えるようになります。影響を受けるアプリケーショは多くありませんが,コネクションプーリング(PHPの永続的データベース接続など)とプリペアードクエリを一緒に使った場合,データベースサーバのリソースが枯渇する可能性があることも触れたほうがよいでしょう。データベースが提供するネイティブのプリペアードクエリを利用していれば,プリペアードクエリがリソース枯渇の原因になることを理解しやすく気がつく方も多いでしょう。セキュリティ対策を行ったために別のセキュリティ問題が発生することはよくあることです。開発者が気づかない場合も多いので補足しておくとよいと思います。

ヘルパー関数やプリペアードクエリ型APIなど出力先の入力仕様を抽象化した,いわゆるモダンなコーディングスタイルを否定しているわけではありません。特に初心者にはこれらのAPIの利用を勧めることはセキュリティ対策として効果的であり,新規プロジェクトなどでは積極的に採用すべきだと考えています。同時に,筆者はより完全なセキュリティ対策を実施できるようになるため,原理や原則を理解した上でセキュリティ対策を行うべきであると考えています。例えば,出力に関しては「エスケープ処理を行う」が原則であり,まずエスケープ処理を知りましょうと提案しています。エスケープ処理を知ることが,出力先の入力仕様を知ることになるからです。入力仕様を正しく知れば,確実に安全な出力とはどのような出力なのか理解でき,開発者が独自に出力先の抽象化を行うような場合でも正しい処理を行えるようになります。

セキュリティ対策は利用しているDBMSサーバやライブラリ,フレームワークによって異なります。特定の環境に対するセキュリティ対策であればデザインパターン的なセキュリティ対策が効果的です。特定の環境を想定しないセキュリティ対策であれば原理・原則を理解するセキュリティ対策が効果的です。どちらが優れているというものではなく,デザインパターン的なアプローチ,原理・原則に基づくアプローチは適材適所で利用すべきアプローチです。

※9

ロックが必要な場合,2フェーズロックを用いないとデッドロックを起こすなど。

まとめ

セキュリティ対策(セーフガード)は必要条件と十分条件の両方を満たしていなければならない,とお考えの方も居たのではないでしょうか? セキュリティ対策には必要条件しか求められていません。何らかの形でセキュリティに役立つ対策であれば何でもセキュリティ対策です。セキュリティ対策の十分条件は実際のプロジェクトにおいて要求される条件です。

必要条件しか求められていないので,セキュリティ対策(セーフガード)はいつでもセキュリティ対策です。 特定のシステムに適用する場合は⁠必要な⁠セキュリティ対策が要件によって変化するだけで,セキュリティ対策自体は,セキュリティ対策の定義が変わらないかぎり,普遍です。ISO/IEC 13335-1やISO/IEC 27001-2では必要な対策を「選択」するようにと記述されています。標準規格ではこのように必要条件だけで定義し,実際に実施する場合には定義された用語に制限や条件を付けて利用することはよくあります。このように定義した方がブレがない定義になるので当然です※10⁠。

実際にセキュリティ対策を実施する場合,十分なセキュリティを確保する必要があります。十分なセキュリティを確保するためにはコンテクストが重要です。セキュリティ規格やセキュリティの教科書ではリスク分析を行うように求めています。リスク分析とはコンテクストを理解するための分析でもあります。多くのリスクはリスクの存在を知っていて初めて対策できます。未知のセキュリティ脅威に対する対策はあまり多くありません。

セキュリティ対策をデザインパターンとして定義する方法は,特に新規プロジェクトのセキュリティ対策指針として定義すると非常に効果的です。しかし,セキュリティ対策が必要なプロジェクトは新規プロジェクトばかりではありません。既存のソフトウェア資産に対するセキュリティ対策はその資産に適応したセキュリティ対策の指針が必要です。

セキュリティ対策を原理・原則から考えて対策する方法は一見遠回りに見えます。しかし,十分なセキュリティ対策を行うためには原理・原則から考えるほうが近道である場合も多いです。特に,仕様書に記載された内容をコードにするだけのプログラマから仕様まで考えられるプログラマになるためには,原理・原則から理解したほうが近道です。

一つ一つのセキュリティ対策は難しいものではありません。セキュリティ対策がとらえどころがなく難しく感じられる原因の一つは,用語の定義が曖昧だからではないでしょうか? セキュリティ対策(セーフガード)とはリスクを軽減する対策すべてである,と理解すれば,より簡単に感じられるのではないでしょうか?

※10

分かりやすく言うと,場合によってセキュリティ対策として機能しないようなセキュリティ対策であっても,セキュリティのための対策であればすべてセキュリティ対策である,と定義しています。

著者プロフィール

大垣靖男(おおがきやすお)

University of Denver卒。同校にてコンピュータサイエンスとビジネスを学ぶ。株式会社シーエーシーを経て,エレクトロニック・サービス・イニシアチブ有限会社を設立。
オープンソース製品は比較的古くから利用し,Linuxは0.9xのころから利用している。オープンソースシステム開発への参加はエレクトロニック・サービス・イニシアチブ設立後から。PHPプロジェクトでは,PostgreSQLモジュールのメンテナンスを担当している。

URLhttp://blog.ohgaki.net/

著書