追記: 8月現在では、OWASP TOP 10 2017はWAFのプロモーションになっている、OWASP Proactive Controlsの”全ての入力をバリデーションする”と重複している、などの点が議論になりRCはリジェクトされ11月にリリースを目指して調整中になっています。
追記2:正式版が2017年12月にリリースされました。ここで紹介している脆弱性はA10(10番目の脆弱性)「不十分なログとモニタリング」として登録されました。WAFが必要であるかのような記載が削減されましたが、脆弱性の本質(入力検証しない&対応しないアプリは脆弱なアプリ)は変わりありません。
このテーマついては既にブログは書いています。このエントリでは追加でQ&Aを記載しています。
元々はこのスライドは非公開にするつもりでしたが、公開可能な内容で公開することにしました。
https://www.slideshare.net/yohgaki/2017owasp-top-10
開発会社としてはどうすれば良いのか?と質問を頂いたので追記します。
誰に責任を負わせるのか?誰が負うべきなのか?
基本的な入力バリデーションさえ実装してない場合、対応工数はそれなりの工数が必要になります。
幸い(?)にも日本の場合、IPAはセキュアプログラミングではないセキュアプログラミングを長年啓蒙していたり、セキュリティ専門家とされる人の中には入力バリデーションとそれを利用した攻撃防止策を”セキュリティ対策ではない”、”重要なセキュリティ対策ではない”、”好ましいセキュリティ対策ではない”と長年主張されている方もいます。
開発会社の方々はこれ(セキュリティ専門家のアドバイスの不備)を利用してお客さまに納得していただくのが、最善のアプローチだと思います。
- 「セキュリティ専門家のアドバイスの脆弱性」として取り扱う。フレームワークやライブラリの脆弱性があった場合と同じような扱いとする
- 今のところはほぼ100%のアプリは脆弱であり、特別/特定の開発会社に不備があった訳ではない
- フレームワークもOWASP TOP 10 A7に対応できる機能を提供していない(事が多い)
セキュリティ専門家は常に「これが悪い、あれが悪い」と指摘する側であることが多いです。今回は指摘される側とされても仕方ないでしょう。
要するに「開発会社としての注意義務は払っていたが、フレームワークに問題があったように、セキュリティ専門家のアドバイスに問題があった(ので開発した会社の責任ではない)」というロジックなら通用すると思われます。
100%に近いアプリが基本的な入力バリデーションさえ実装していない点も、開発会社として要求される注意義務として「入力バリデーションを実装してない責任」を負わされる可能性を低くすると思われます。
基本的な入力バリデーションでカバーできる?
セキュアコーディングでいう入力バリデーション(ホワイトリスト型チェック&不正な値で処理を停止&ログを記録)であれば
- 入力バリデーションを実装している場合、最低限の「攻撃防御」はできている。
と考えられます。
A7で要求される追加の「攻撃防御」はアプリで入力バリデーションしていれば多くの物が簡単に実装できます。
入力をチェックしていても、バリデーションではなく「サニタイズ」(不正な入力を変換して受け入れる。デフォルト値を利用するなど)をしている場合は”脆弱”です。
モデルでの入力バリデーションでカバーできる?
MVCモデルならC(コントローラー)で入力バリデーションすべきです。アプリケーションの入出力の境界で実施すべきだからです。M(モデル、つまりアプリ内部)だと遅すぎます。特に保存前のバリデーションしかしない場合は、普通の入力バリデーションに比べ、仕組み的にかなり脆弱と言えます。
しかも多くの場合、モデルでのバリデーションはホワイトリスト型のバリデーションではなく、単なるエラーチェックレベルのバリデーションが多いです。この場合、全く要求事項を満たしていません。
また、エラー処理の基本は”できる限り早くエラーを検出する”です。不正な入力はそもそも、ソフトウェアは一切受け入れるべきではない、致命的エラーです。これを受け入れて処理してしまう構造は”構造的な問題”があると言えます。
入力バリデーションはコントローラーのみで行うモノではないです。モデルで外部サービスなどと通信し入出力がある場合、当然モデルでも入力バリデーションを行います。
データ型が一致していることを保証するコードになっていれはOK?
いいえ。全く不十分です。データ型が一致することを保証するだけでは、一番問題となる”文字列型”のデータバリデーションが不十分です。
セキュアプログラミングでは数値は”範囲”もバリデーションします。範囲外の数値は最悪の場合、任意コード実行も許してしまいます。
データ型を保証する対策は”非常に弱いバリデーション”でしかありません。入力バリデーションの代わりになるモノではありません。
追加機能となる部分の負担は?
基本的な入力バリデーションでの処理を越える、IPをブロック、ユーザーログアウトさせる、怪しい入力も検出する、頻繁すぎるリクエストを防止する、などの動作は
- 追加の部分は、「単純に新しい脆弱性タイプ」として「新機能として実装」する
が妥当でしょう。
これらの動作をアプリケーションで実装しているケースは「入力バリデーションを実装」しているケースより更に少ないと思います。ユーザー負担の機能として実装するのが普通だと思います。
セキュリティ標準やセキュリティガイドラインの間違いではないか?
基本、間違いはありません。
一私企業が作ったガイドラインには不適切なモノもあるかも知れません。IPAが公開していた「セキュアプログラミング講座」がセキュアプログラミングではない問題などもあります。
しかし、公的なセキュリティ標準/ガイドラインではISO27000やOWASP、SANS、CERTなどは「入力はバリデーションすること」を一貫して最重要セキュリティ対策の1つとして要求してきました。
このため、セキュリティ標準やセキュリティガイドラインに不備があった、などとするのは間違っています。このような説明にはリスクがあるので注意が必要です。
弊社及び私個人は一貫して「入力バリデーションとそれを利用した防御策」を最重要ソフトウェアセキュリティ対策としてお勧めしてきましたが、「重要なセキュリティ対策を知らず、または誤解して、セキュリティ関連のアドバイス」をしているケースは多く知っています。この場合、ガイドラインなどの間違いではなく、その個人や会社の間違いです。
簡単に対応する方法は?
PHP向けになりますが、入力バリデーションコードを容易に追加できるモジュール
https://wiki.php.net/rfc/add_validate_functions_to_filter
(残念ながらこのはPHP本体のRFC(機能追加提案)としては棄却されました)
を3rdパーティモジュールとして配布予定です。これを使用した場合、OWASP TOP 10 A7が要求する「攻撃防御」をかなり容易に”後付け”できます。