「黒い」セキュリティだのみは捨て去る

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

「黒い」セキュリティとはブラックリスト型セキュリティのことです。

ブラックリスト型セキュリティとは「ブラックリスト型対策でセキュリティを維持しよう」とする概念です。セキュリティ対策では、ブラックリスト型対策はできる限り使わず、可能な限りホワイトリスト型対策を使う、が基本です。しかし、ブラックリスト型の「黒いセキュリティ」対策が理想的な対策である、と考えている人が少くないようです。

「黒いセキュリティ」に頼ったITセキュリティは基本的に捨て去るべきです。

セキュリティ対策の基本

セキュリティ対策の基本は

  • リスクの識別/認識

を行い

  • リスクに対して対策/対応

します。リスクに対する対応策(=セキュリティ対策)はホワイトリスト型で対応します。

  • 許容するリスクは受け入れる
  • 許容不可能なリスクは廃除/削減/緩和する

ブラックリスト型とホワイトリスト型の違いを見てみましょう。

参考:

ブラックリスト型のセキュリティ

ブラックリスト型のセキュリティ対策は

  • リスク(脆弱性)として識別/認識したモノだけに対して対策/対応

します。一見これで全てのリスクに簡単に対策/対応できそうに思えますが、そうではありません。

ブラックリスト型のセキュリティがホワイトリスト型のセキュリティと同じように機能するには「全てのリスクを完全に識別/認識した上で完全に対策する」必要があります。しかし「全てのリスクを完全に識別/認識」することも「全てのリスクを完全に廃除すること」も簡単ではありません。

これは今までに見つけられたセキュリティ問題を見れば明らかです。「今まで知らなかった!」という攻撃手法や脆弱性が年とともに明らかになってきました。セキュリティ専門家でさえ「知らなかった」攻撃手法や脆弱性があるのです。

解っている脆弱性であっても対策が困難な場合もあります。解りやすい例はJavaScriptインジェクション問題です。JavaScriptインジェクションの原理とリスク排除の仕組みは簡単ですが、現在の複雑化したソフトウェアでは簡単ではありません。これはHTMLに出力する場合にタグなどを含めたモノが必要であることが大きな理由です。

できる限り安全にHTML出力を行うフレームワークやAPIを使っていても、その内部で完全にJavaScriptインジェクションを防ぐ仕組みになっていないとリスクを廃除できません。出力が行われるまでに複数のAPIが呼び出され、呼び出し順序も状態によって変わったりします。「出力が完全にJavaScriptインジェクションに対して安全である」ことを保証するのはかなり難しいです。

このため、広く利用され、検証が進んでいるフレームワークでさえ「仕組み的には対策が簡単なハズのJavaScriptインジェクション」でえブラックリスト型セキュリティ対策では完全に防ぐ事ができず、JavaScriptインジェクション脆弱性が度々発見されています。

参考:

比較的コードの検証が進んでいるフレームワークでさえ、JavaScriptインジェクション問題を完全に防ぐことに成功していません。クローズドソースのアプリケーションでは無視できない大きなリスクと言えるでしょう。

ホワイトリスト型のセキュリティ

ホワイトリスト型のセキュリティ対策は

  • 全てをデフォルトで拒否して対策/対応

します。(ホワイトリスト型の優位性を理解できていない方は、”全てデフォルトで拒否”の”全て”を解っていないようです。注意してください)

この方法の利点はリスクの廃除/緩和を行う為に「全てのリスクを知らなくても構わない」ことです。「全てのリスクを知らなくても構わない」は「未知の脆弱性やケアレスミスによる間違いにも対応できる」ことを意味します。

セキュリティ専門家がセキュアプログラミング第一位の対策として

  • ホワイトリスト型の入力バリデーション

を挙げているのはこれが理由です。安全なプログラムを作るには「全てをデフォルトで拒否して、許可された入力だけを受け入れる」という考え方が欠かせません。

ブラックリスト型のセキュリティでは「問題である」とされた部分にのみ対策します。

  • 脆弱性としたリスクにしか対応できない
  • 複雑な処理を行う処理のリスクへの対応が不十分
  • 脆弱性と認識しなかったリスクが放置される

といった問題があり「システム全体として十分なリスク対応が困難」になります。ホワイトリスト型のセキュリティの方がより安全性が高いことは論理的にも、実証的にも明らかです。

黒いセキュリティは捨て去るべき

十分に安全なソフトウェアを作りたいなら、ブラックリスト型セキュリティに頼った作り方は止めるべきです。

JavaScriptインジェクション対策として

  • デフォルトで全ての出力をHTMLエスケープする

が提唱され、実践されてからJavaScriptインジェクション問題がかなり低減されました。デフォルトで全ての出力をHTMLエスケープする対策はホワイトリスト方式の対策です。言い換えると

  • 全てデフォルトでHTML出力は拒否し、安全であると保証できる出力のみHTMLエスケープを行わないで出力する

です。経験豊富なWebシステムの開発者であれば、この方式に変えて以前と比べるとかなり安全性が向上したことを解っていると思います。

より安全なシステムを構築するには

  • 黒いセキュリティ(=ブラックリスト型セキュリティ)は極力廃除する

は必須です。

この考え方は特にソフトウェアの安全性確保に重要です。”黒いセキュリティの脆弱性”は「デフォルトで全ての出力をHTMLエスケープする」という対策の結果だけを見ても明らかです。いつまでも黒いセキュリティだけに頼り、ホワイトリスト型対策である「入力バリデーションはセキュリティ対策ではなくアプリケーション仕様である」などとするレトリックに頼るのは賢いとは言えません。さっさと黒いセキュリティだけに頼る考え方は捨て去るべきです。※

※ 複雑なソフトウェアでは出力時のホワイトリスト対策だけでは不十分です。OWASP TOP 10ではホワイトリスト型入力バリデーションを対策として行なうように推奨しています。

Preventing XSS requires separation of untrusted data from active browser content.

  1. The preferred option is to properly escape all untrusted data based on the HTML context (body, attribute, JavaScript, CSS, or URL) that the data will be placed into. See the OWASP XSS Prevention Cheat Sheet for details on the required data escaping techniques.
  2. Positive or “whitelist” input validation is also recommended as it helps protect against XSS, but is not a complete defense as many applications require special characters in their input. Such validation should, as much as possible, validate the length, characters, format, and business rules on that data before accepting the input.
  3. For rich content, consider auto-sanitization libraries like OWASP’s AntiSamy or the Java HTML Sanitizer Project.
  4. Consider Content Security Policy (CSP) to defend against XSS across your entire site.

黒いセキュリティだけではセキュリティ問題を解決できない

ソフトウェアは常に進化、つまり変更され続けています。仮に特定の時点で一時的に完全な安全性を確保できていた、としても変更に伴いセキュリティ問題が入り込むことが起きています。

特定の脆弱性に対してのみ対策を行う黒いセキュリティ対策だけでは、合成の誤謬が発生し満足できる状態の達成が困難になります。ブラックリスト型のセキュリティ対策だけでは不十分です。

プログラムは基本的に「入力」「処理」「出力」の組み合わせでタスクを実行します。リスク(脆弱性)に着目するブラックリスト型のセキュリティ対策の場合、「処理」「出力」にだけ対策することが多いです。「処理」が変更(最適化や利用する外部システムの変更など)されることは比較的多く、それに伴い「出力」が変ることも多いです。複雑なソフトウェアの場合、これらの変更で致命的な脆弱性が入り込むことが少くありません。

例:

  • DBをRDBMSからMongoDBに切り替えた為に配列型の入力によるインジェクションが可能になった

十分なセキュリティの為にITセキュリティ対策の目的を忘れない

セキュリティ対策の目的は

  • ITシステム利用のリスクを許容可能な範囲内に抑えて利用する

ことにあります。闇雲に「リスクを削減する対策を行う」ことはITセキュリティの目的ではありません。

  • 許容可能なリスクは、認識/識別した上でリスク対策として許容する

考え方が欠かせません。リスクの許容とその管理はセキュリティ/リスク対策で欠かせない基本概念です。解りづらいようですが、リスクの削減/廃除だけがセキュリティ/リスク対策ではない、ことは理解する必要があります。

ITセキュリティ対策は

  • リスク(脆弱性)を廃除/削減する対策

ではなく

  • リスク(脆弱性)を管理する対策

であり、リスク(脆弱性)を管理する対策には

  • リスクの許容、リスクの廃除/削減/緩和、損害の補填

などが含まれます。前者は非体系的な(論理的に矛盾があり体系的でない)セキュリティの考え方であり、後者は体系的なセキュリティの考え方です。

「許容したリスク」はセキュリティ対策として管理しなければならない点は忘れてはならず、乱用は厳禁です。インターネットに公開するシステムの場合、攻撃者のコード/命令を実行する問題(マシン語、SQLやJavaScriptインジェクションなどの任意コード実行、CSRFやセッションハイジャックなどの真正性問題、など)はどこから見ても「許容可能なリスク」ではありません。※

※ リスクが許容可能かどうか?の判断は難しいですがOECDセキュリティ勧告を参考にすると良いでしょう。

まとめ

ブラックリスト型のセキュリティ対策がITセキュリティの為に全く役立たない、ということはありません。しかし、ホワイトリスト型のセキュリティ対策が実施可能であるにも関わらず、ブラックリスト型だけ、ブラックリスト型に偏重するのはベストな選択肢とは言えません。

ブラックリストがホワイトリストより脆弱であることは明らかです。昔は居ましたが今では「ブラックリストもホワイトリストも変わらない」とするセキュリティ専門家も居なくなったと思います。(ホワイトリスト型対策の入力バリデーションが、セキュリティ対策ではない、とする意味が分らない主張はまだあるようです。惑わされないようにしましょう。)

ブラックリスト型の「黒いセキュリティ」は基本的に捨て去さり、可能な限りホワイトリスト型のセキュリティ対策を導入/実施することが「ITセキュリティの目的達成」の近道です。「黒いセキュリティ対策」は不可避な場合のみ利用しましょう。

バリデーションには3種類のバリデーションがある 〜 セキュアなアプリケーションの構造 〜

参考

基本はホワイトリスト型のチェック&ゼロトラストで何もかも検証する、です。

ゼロトラストとフェイルファースト
バリデーションには3種類のバリデーションがある 〜 セキュアなアプリケーションの構造 〜
ほぼ全てのインジェクション攻撃を無効化/防止する入力バリデーション 〜 ただし出力対策も必須です 〜

コンピューターサイエンティストやセキュリティ標準/ガイドラインを作っているソフトウェアセキュリティ専門家が提唱しているセキュアなアプリケーションアーキテクチャーは、悪いモノを潰す、もぐら叩き型の場当たりセキュリティ構造ではありません。

セキュアコーディングの構造/原理/原則

投稿者: yohgaki