炎上プロジェクトの主な原因の1つに、システム要求定義が不明確であること、があります。何を作ったらよいのか、よく分らない状態で作って上手く行くのを願うのは、サイコロを振るのと変りありません。
これと同じことが情報セキュリティ対策でも起きています。
致命的な脆弱性が残っているシステムの主たる原因の1つに、セキュリティ要求定義が不明確、ならまだよいのですがセキュリティ要求定義なし、であることが少なくない数あります。IoTやスマートカーのセキュリティを見れば明らかです。セキュリティ要求定義が不明確か無い状態で作った、としか思えない事例が数えきれません。
漏れのないセキュリティ要求定義には漏れのないリスク分析が必要です。
- ◯◯対策として△△を実施する
といったセキュリティ仕様をセキュリティ要求だと勘違いしているケースも数えきれません。
システム要求定義がないプロジェクトが簡単に炎上するように、セキュリティ要求定義がないシステムも簡単に無視することが不可能な脆弱性だらけのシステムになります。
特にソフトウェアの分野では「リスク分析」が不十分過ぎる、さらには全く無い、システムで溢れています。これでは十分な安全性を効率良く達成することは不可能です。
情報セキュリティ対策とリスク対策/リスク分析
情報セキュリティ対策はリスク対策のサブセットです。リスク対策の基本を知る=情報セキュリティ対策の基本を知ることになります。
ざっくりとリスク対策を定義すると以下のようになるでしょう。
不確実性を緩和/排除/管理する
これはISO 27000のリスク分析/対応の定義を、ざっくり、とまとめた物になります。詳しくはISO 27001などを参照してください。
不確実性を緩和/排除/管理するにはまず、どのような不確実性があるのか認識しなければなりません。つまり、リスク対策(=セキュリティ対策)を実施する前に
- リスク分析
が必要です。網羅的なリスク分析を行って初めて網羅的なセキュリティ要求を定義できます。
システム開発とセキュリティ対策のプロセスはほぼ同じ
ウォーターフォールでもアジャイルでも、システム開発では
システム要求定義 → システム仕様定義 → システム仕様実装 → システム実装テスト
の順序で行います。アジャイルの場合はサイクルが短いだけ、TDDの場合は「実装テスト → 仕様実装」の順序になるだけ、です。
セキュリティ対策も同じ順序で行います。
セキュリティ要求定義 → セキュリティ仕様定義 → セキュリティ仕様実装 → セキュリティ実装テスト
当たり前のようですが、この当たり前が出来ていないケースが山のようにあります。簡単にIoTが悪用される、簡単に自動運転車の制御が乗っ取られる、簡単にシステムを不正な動作をさせる、こういったケースは後を絶ちません。
簡単に対処可能な単純な脆弱性が残ってしまう主たる原因は
- セキュリティ要求定義
が間違っていることにあります。
”セキュリティ専門家”とされる暗号系のスペシャリストが定義した暗号処理の仕組みでも、多数の要求定義漏れによる脆弱性が見つかっています。専門家でも間違えてしまうのに、一般開発者がセキュリティ要求定義を無視して良いはずがありません。(普通のアプリの場合、難しくはありません。当然思い付くであろうリスクを全てリストアップし対応するだけです)
今時はほぼありませんが、セキュリティ要求が一切ないと仮定したシステム開発だとします。要求定義から間違っていたら、簡単に対策可能な問題であっても、単純かつ致命的な問題が残ってしまいます。作る対象の目的となる要求定義間違っているのでは目的に合わないモノを作ってしまうのは当然でしょう。まず要求定義が正しくなければ、正しいシステム構築は不可能です。
セキュリティ対策も同じです。セキュリティ要求から間違っていると、単純でも致命的な問題が残ります。実際、このようなインシデント/事例は枚挙にいとまがありません。
セキュリティ要求定義に必要なモノ – リスク分析
まずどんなモノが必要なのか?理解していないと必要なモノを定義できません。セキュリティ対策では脅威を認識することが重要だ、と言われるのはセキュリティ要求を理解する為に必要だからです。
しかし、個々の脅威を理解し対策することはリスク分析ではありません、残念ながら。
リスク分析とは「個々の脅威を識別する」のではなく「全ての脅威(不確実性)を識別する」ものです。情報システムにとんでもないセキュリティ問題が残ってしまうのは全ての脅威(不確実性)を識別していないこと、つまりリスク分析が不十分か全く行われていないことが主な原因の一つです。
「全ての脅威(不確実性)を識別する」ための分析がリスク分析です。もちろん分析に誤り/漏れがある事もありますが、リスク分析を行わない、のは明らな問題です。
※ かなり荒い要求仕様として CERT Top 10 Secure Coding Practices が参考になります。CERTとは”習慣”としていますが、IPAは2017年からセキュアプログラミングの”原則”として紹介しています。
リスク分析を行わない事による間違い
少なくない開発者が
- SQLインジェクション対策はプリペアードクエリ/プレイスホルダを使っていれば万全!
と勘違いしていました。
実例:SQLインジェクション対策で大垣靖男氏は何を勘違いしていたか
(上記はarchive.orgのURLです。現時点で実ページも残っており、勘違いの訂正はありません。より安全なコード記述を推奨しているつもりで、非論理的で脆弱なコード記述を推奨している事に全く気付いていないようです。プリペアードクエリだけで十分!として喜ぶのはセキュリティ業者と犯罪者だけでしょう)
プリペアードクエリ/プレイスホルダだけでは、識別子やSQL語句を利用したSQLインジェクション攻撃は防げません。当たり前の事ですが誤解してしまった方は少くないようです。ここではSQLインジェクションは詳しく解説しません。正しくSQL文実行に関連するリスクを分析した上での対策例は以下のブログを参照してください。(実はこれでも、まだリスク分析つまり「全ての脅威(不確実性)を識別する」が足りない/省略している部分があります!)
テキストインターフェース(SQL、HTMLなどWebアプリ関連の技術ほぼ全て)を正しく処理するには、エスケープは欠かせない基礎知識、なのですが「エスケープなど教える必要がない」といったおかしな議論でも一定の支持を得てしまうことは残念です。
※ SQLは素人でも容易に使える便利な言語とされています。そのSQLの基本がプログラマにとって難しい、とするのはおかしな話でもあります。
リスク分析を行わないリスク
リスク分析を行わないリスクは言うまでもないでしょう。SQLインジェクション対策の間違いや単純なセキュリティ仕様の実装漏れは数えきれません。
これらは”普通”にリスク分析をしていたら回避できるものがほとんどです。
(ISO 27000/31000などの標準で定義されたリスク分析を普通に行なえば”普通”/”当たり前”に回避できていたはずです)
セキュリティ専門家でなくてもリスク分析は必ず行うべきシステム開発での必須作業です。今あるソフトウェアの大半が基礎的なリスク分析/対策ができていないので尚更です。
セキュリティ対策を仕事とする人であっても「◯◯用のリスク分析は必要ない。対策は解っているのだから、単純に対策を実装すればよい」として「◯◯だけを使っていれば良い」と不十分かつ誤った解説をしているケースも見かけます。
「完全なSQLインジェクション対策」のような解説をせず、不十分なセキュリティ対策はセキュリティ業界の仕事を増やすことには好都合です。ウィルスが蔓延すればアンチウィルスベンダーが儲かるのと同じで、脆弱性が蔓延すれば脆弱性対策を行うセキュリティ業界が儲かります。
※「出力対策だけがセキュリティ対策」と捉えている方も少くないと思います。これもリスク対策的には大きな勘違いです。出力対策の半分は「フェイルセーフ対策」で主たるセキュリティ対策とは役立ちません。
リスク分析の基本を理解していれば、「出力対策だけがセキュリティ対策」といった不確実性(=リスク)を増やすセキュリティ業界の為のセキュリティ対策、になっているのか?いないのか?容易に判別できるようになります。
長年感じているのですが、”セキュリティ業界人”とされる人達が、ISOやJISなどの標準に反し、セキュリティ業界の仕事を増やす”セキュリティ対策”を啓蒙しているケースが多すぎるように感じています。
取り敢えず「リスク分析は必要ない」はとんでもない間違いです。自己流でも構わないのでリスク分析は行いましょう。体系的なリスク分析を知らなくても「ゼロトラスト」と「フェイルファースト」で分析/対応すると、自分自身でかなりの精度でリスク分析できると思います。
基本的なリスク分析ができれば、SQLインジェクション対策で大垣靖男氏は何を勘違いしていたか、といったような間違いをしなくなります。
ソフトウェア向けリスク分析方法の簡単な説明は別のブログで書きました。
ゼロトラストとフェイルファースト原則で作れば、適切なリスク分析とリスク対応に自然となります。
リスク分析とリスク対応は究極のセキュリティ要求である「情報システムが正しく動作することを確実にする」を意識すると、より確実です。