(Last Updated On: 2018年9月28日)

ITセキュリティ対策の概念で最も足りていないモノは「構造化」ではないでしょうか?

システム開発者は常に「システムの構造化」を考えています。構造化プログラミング、オブジェクト指向設計、DoA、DDDなど「システムの構造化」には様々な構造が考えられています。

何故か「セキュリティの構造化」を十分考えていないのが現状です。その結果、「”基本構造が無い”場当たり的セキュリティ対策」に終始しています。

場当たりITセキュリティ対策

場当たり的対策とは

  • 物事に直面したとき、そのときの思いつきで対応すること。事前に準備したり計画を立てたりしていないこと。

ITシステムの脆弱性でいうと「セキュリティ対策の構造」を考慮せず「構造化」しないこと、脆弱性が発生した箇所をモグラ叩き的に対処するセキュリティ対策を実施することです。

例えば、ソフトウェアにインジェクション脆弱性があった場合、

  • エスケープを忘れるからエスケープが必要ないAPIだけ使えば良いと考えて利用する。
  • エスケープが漏れていたからエスケープする。

これらには「構造」がありません。

  • 問題が起きた箇所を逐次修正する。

事前の備えも、対策の構造化もありません。これが「場当たりITセキュリティ対策」です。これで十分な安全性が確保できるのであれば問題ないのですが、一部のリスクを減らしても、不必要にリスクの残していたりするので問題が残ったまま、になっているケースは少なくありません。

SQLインジェクションやOSコマンドインジェクション対策といった比較的簡単に防御できる問題に不必要なリスクを残しているケースはとても多いです。

完全なSQLインジェクション対策

コマンド実行時、コマンドと引数を分離すれば完璧?

こういった脆弱な対策が現在のITシステム開発の現場で一般的に行われています。

「場当たりITセキュリティ対策」に終始する原因は、”セキュリティ専門家”も含めて「ITセキュリティの構造」を無視したセキュリティ対策だけを啓蒙していることが原因でしょう。IPAでさえデタラメな構造のセキュリティ対策を啓蒙していました。「ITシステムのセキュリティの構造とは?」と聞いて、正しく解答できる技術者は少ないのではないでしょうか?

”構造がないプログラムを管理することが不可能である”のと同じく、”構造がないセキュリティでは管理することは不可能である”です。

ITセキュリティ対策の構造

「ITセキュリティ対策の構造」といっても特別なモノではありませんIT以外のセキュリティ対策と基本は全く同じです。

  • 守るべきモノを定義する
  • 守るべきモノに対する脅威を識別する
  • 守るべきモノに対する外部からの脅威(改ざん/破壊/盗難など)を廃除/削減する
  • 守るべきモノが外部に出る場合の脅威(改ざん/破壊/盗難など)を廃除/削減する
  • どこで守るか定義する

ITシステムの場合、ISO 27000で定義されています。

  • 守るべきモノ:モノ/データ/機能
  • 脅威:不完全な機密性/完全性/可用性/信頼性/真正性/否認防止(責任追跡性)

ITシステムは

  • モノ – 物理的なデバイスやネットワークケーブルなどの”物”とユーザーや開発者などの”者”
  • データ – ITシステムが処理する情報
  • 機能 – ソフトウェアやハードウェアが実現する機能(基本データを処理する機能) 

の3つで構成されています。これらに対する上記の脅威をITシステムが利用可能な程度までに削減&管理する、のが情報セキュリティ対策です。(これもISO 27000のセキュリティ定義)

ソフトウェアのセキュリティ対策が構造化されていない原因

色々な原因が考えられますが、ここでは

  • どこで守るか定義する

が構造化されていない点を取り上げます。

”モノ”はどこで守るのか?

”物”を守る場合、”物”にできる限り触れることが出来ないようにして守ります。例えば、サーバーのように重要な情報や機能が集中している”物”は許可された”者”だけが直接触れれるよう、鍵をかけた別の部屋などに分離して守ります。

“者”(人)からの脅威を守る場合はできる限り許可された人だけが”物”に触れるようにして守ります。例えば、オフィスやサーバールームへの入退室を管理し、許可された人だけが”物”、”データ”、”機能”に触れれるようにします。

”物”も”者”も、出来る限り守る対象から出来る限り離れた場所の入り口から対策します。重要な”モノ”に対しての入り口対策は通常は何重もの入り口対策を行います。

基本対策:”物”は可能な限り、許可された”者”だけが触れるよう分離し、可能なかぎり”物”から離れた場所から防御対策を行う。一般に重要性が高い”物”ほど複数の防御対策が必要となる。

”データ”はどこで守るのか?

現在のコンピューターシステムはネットワークなしで独立して稼働する”物”は少数派です。

守るべきネットワークへの入り口をできる限り絞り、許可された”モノ”(”物”と”者”の両方)だけが”モノ”、”データ”、”機能”に触れることが出来るようにします。入り口ではデータが妥当なデータであるかどうかの検証も可能な限り行います

ネットワークがない”物”でも、同じ考え方です。形がない”データ”であっても、何らかの”物”にデータを保存・管理する必要があります。ネットワークがない場合、物理的な”モノ”(”物”と”者”の両方)の脅威を管理すれば良いので話は簡単です。

ネットワークがある場合、守るべき”データ”がネットワーク経由で移動・複製・改ざん・削除できてしまいます。これが”データ”のセキュリティ管理を難しくしています。

”ネットワーク”も、出来る限り守る対象から出来る限り離れた場所の入り口から対策します。重要な”ネットワーク”に対しての入り口対策は通常は何重もの入り口対策を行います。

基本対策:”データ”は可能な限り、許可された”モノ”だけが触れるよう、可能なかぎり”データ”から離れた場所から防御対策を行う。一般に重要性が高い”データ”ほど複数の防御対策が必要となる。

”機能”はどこで守るのか?

ITシステムの”機能”には物理的なデバイスにより実現している機能とソフトウェアにより実現している機能の2種類があります。物理的なデバイスの保護は”モノ”の防御対策で保護できます。ここではソフトウェアで実現している機能の保護のみを考えます。

ここで考慮する”機能”であるソフトウェアに対する脅威は多岐に渡ります。代表的な脅威には

  • ”データ”によって”機能”が誤作動する(コードのバグも一因だが、大半は不正/デタラメなデータが原因)
  • 機能の誤作動により、”データ”が改ざん/漏洩する

があります。これはいわゆるインジェクション脆弱性の脅威です。OWASP TOP 10では第一番目の脅威としています

インジェクション脆弱性は”データ”によって発現します。もちろん不十分な”コード”も原因の一つです。しかし、どんなプログラムも基本構造は同じです。

  1. 入力処理
  2. ロジック処理
  3. 出力処理

の構造を持っています。基本対策は”モノ”/”データ”の対策と同じです。

”機能”も、出来る限り守る対象から出来る限り離れた場所の入り口から対策します。重要な”機能”に対しての入り口対策は通常は何重もの入り口対策を行います。

基本対策:”機能”は可能な限り、許可された”モノ”/”データ”だけが触れるよう、可能なかぎり”機能”から離れた場所から防御対策を行う。一般に重要性が高い”機能”ほど複数の防御対策が必要となる

守りたいモノは出来る限り離れた場所から防御する

守りたいモノがある場合、出来る限り離れた場所から対策を行います。家の中に守りたいモノがあるから金庫だけを買い、窓や玄関ドアを全開・鍵も無くす、などという対策は普通は行いません。

物理的なセキュリティ対策、ネットワークのセキュリティ対策では境界防御と多層防御は当たり前に行われています。

ソフトウェア、特にWebアプリ、ではどうでしょうか?

サーバー側に置かれたWebアプリの「入り口」は対策されている、とは言えないのが現状です。Struts 2の脆弱性もDrupalの脆弱性も

Webアプリは防御対策が構造的に作られていないのが現状です。デタラメなデータが入り放題、デタラメなデータも保存し放題、となっている仕様の機能が山ほどあります。

pg_query_params($db, ‘UPDATE mytable SET name = $1 WHERE id = $2’, [$_POST[‘name’], $_POST[‘id’]]);

このPHPコードによるクエリはPostgreSQLのネイティブプリペアードクエリで$_POST[‘name’], $_POST[‘id’]パラメーターを渡しているので「SQLインジェクションは防止」しています。

しかし、プリペアードクエリだけでは$_POST[‘name’]にはほぼ何でも保存できてしまいます。スペースでも改行でも制御文字でも記号でも、文字エンコーディングがUTF-8ならUTF-8の特殊文字でも、保存出来てしまいます。

”データ”は守りたいモノの一つです。一つというより”データ”の保護が最大のITセキュリティ対策の目的です。SQLインジェクションだけを防止しても、直接デタラメなデータをインジェクションできてしまうようでは”データ”を守っている、とは言えません。

アプリケーションで考えると、まず入力処理で”データ”が正しい(=アプリケーション入力データとして妥当である)ことを検証して保証しなければなりません。ソフトウェアの基本構造は

  1. 入力処理
  2. ロジック処理
  3. 出力処理

なので、まず入力処理でのデータバリデーションが必須となります。

ところで「出来る限り離れた場所で対策する」はフェイルファースト原則です。フェイルファースト原則どのようなセキュリティ対策にも通用する普遍的な基礎原則です。

入力データバリデーションはセキュリティ対策ではない、重要ではない、というデタラメ

「入力データバリデーションはセキュリティ対策ではない、重要ではない」は「玄関や窓の戸締りはセキュリティ対策ではない、重要ではない」とすることと同じです。

「入力データバリデーションは内部の脆弱性を隠す対策だからよくない」は「玄関や窓の戸締りは脆弱性を隠す対策だからよくない」とすることと同じです。

セキュリティ専門家から「玄関や窓を解放して誰でも出入りできるようにしないと、金庫に鍵がかかっているか、十分に頑丈か外から入ってチェックできなくなるから戸締りはダメな対策なのです」と説明されたら「デタラメな解説だ」と思うです。

ソフトウェアだと同じ説明をされて納得してしまうケースも少なくないようです。

「(どんなデータでも受け入れるように解放し)コードがインジェクション攻撃を防止しているのか、十分にライブラリなどが安全か外から入ってチェックできなくなるから入力データ検証はダメな対策なのです」

とんでもなくデタラメなセキュリティ対策指南ですが、これと全く同じ説明をセキュリティ専門家から直接聞いたことがあります。

基礎の基礎から壊れている、デタラメなセキュリティ構造・対策ではいつまで経っても壊れた&デタラメなセキュリティ構造・対策のままで、十分に安全になることはありません。

セキュアなソフトウェアの構造

セキュアコーディング、コンピューターサイエンスの基礎から導き出されるセキュアなソフトウェアの基本構造は以下のようになります。

とてもシンプルで解りやすい物ですが、ソフトウェア開発者は「機能の構造化」に手一杯で「データセキュリティの構造化」にまで気が回っていないのが現状のようです。

一部のセキュリティ専門家と呼ばれる”専門家”が根本的に間違ったデタラメなセキュリティ対策を10年以上も啓蒙し続けている、IPAもデタラメなセキュリティ対策を啓蒙していたことも大きな要因だと思われます。

ITセキュリティの大きな目的の一つは”データ”をセキュアに扱えるようにすることです。”データ”そのものをセキュアにする、という観点を欠いたり、軽視したりするセキュリティでは不十分なままとなってしまうのは仕方ないでしょう。

投稿者: yohgaki