第一のソフトウェアセキュリティ原則さえ普及しない最大の理由とは?

(Last Updated On: 2017/12/25)

セキュアコーディングの原則1は「入力バリデーション」です。セキュアコーディングの原則1はソフトウェアセキュリティの一丁目一番地と言えるセキュリティ対策です。

入力バリデーションを第一のセキュリティ対策としているガイドライン

90年代初めから提唱された防御的プログラミングから数えると四半世紀を越える月日が経っています。

国際情報セキュリティ標準(ISO 27000/17799)は2000年からセキュアコーディングの原則1の実装方法を具体的に記述&要求しいました。2013年の改定でセキュアプログラミング技術が体系化され普及したとし、セキュアプログラミング技術を採用するとした簡潔な記述になりました。

OWASPをはじめセキュリティガイドラインを公開している複数のセキュリティ機関がセキュアコーディングの原則1の入力バリデーションを第一のセキュリティ対策、最も重要なセキュリティ対策として紹介しています。

にも関わらず、「まともな入力検証を持ったアプリケーション」は日本のみでなく世界的に普及していません。

ソフトウェアセキュリティの一丁目一番地、と言えるセキュリティ対策がほとんどアプリケーションで実施されていない、その最大の理由をズバリ・・・

セキュアコーディングが流行らない最大の原因は”著名なIT専門家”の誤解にある(のでは?)

ソフトウェアセキュリティの専門家はそもそも誤解などはしていません。ソフトウェアセキュリティが必要になったモリスワーム事件以降、90年代初めから論理的に妥当なセキュアコーディングを一貫して提唱しています。

国際情報セキュリティ標準(ISO 27000)やCERT、OWASP、SANS、MITREなどが公開している資料からセキュアコーディングで最も重要なセキュリティ対策は「入力のバリデーション」としていることが明らかです。

問題の原因は影響力が強いIT専門家の行動と態度だと思われます。

  • セキュアコーディングの知らない、知るつもりがない
  • ”セキュアコーディングではない設計”を”セキュアコーディング”だと勘違いしている

これらの事例を紹介する前に、なぜコンピューターサイエンティストが入力バリデーションを第一のセキュリティ対策としているのか解説します

正しくプログラムを実行するには、コードが正しく処理できるデータが必須である

セキュアコーディングは「脆弱性を作らないように書く」とする考え方で作られていません。

セキュアコーディングは「コードが確実に正しく動作するように書く」を実現することを目的にしています。

「脆弱性を作らないように書く」は悪いモノを定義し禁止するブラックリスト型の対策で仕組み的に脆弱です。「コードが確実に正しく動作するように書く」は良いモノを定義し許可するホワイトリスト型の対策で、「脆弱性を作らないように書く」に比べ遥かに堅牢です。

脆弱性を利用した攻撃はプログラムが意図しないデータ(≒不正な入力)を与えて誤作動させることで行われます。そもそもプログラムが意図しない不正なデータを受け入れなければ(ホワイトリスト型のセキュリティであれば)攻撃そのものが不可能となるケースは多数あります。

C言語などでは整数型(8、16、32、64ビット整数など)の入力でさえデータバリデーションをしないと、オーバー/アンダーフローしないこと保証できません。整数オーバーフローは時として予想外の攻撃を可能にします。例えば、MySQLでは符号付きchar型、符号なしchar型の違いにより管理者権限でのログインができてしまう問題がありました。

任意精度整数をサポートするRuby/Python3を使っているから整数オーバーフローなど関係ない!?と考えるかも知れませんが、それは間違いです。Ruby/Python3が利用するライブラリの多くはCやC++で記述されています。一般にCやC++の関数は、任意精度整数は使いません。ライブラリ内では64/32/16/8ビット整数を使い、さらに符号の有り無しがあります。

単純な整数型でさえ、オーバーフローにより不正な動作を起すことが可能です。より複雑な文字列型データの場合、データバリデーションを行わないとありとあらゆる脆弱性のリスクが生まれます。

セキュリティ対策とはリスク管理です。できる限り効率的かつ効果的にリスクを排除・削減することを目標にします。入力バリデーションは”プログラムが意図通り動作するために必須”であると同時に、”プログラマが予想していない脆弱性さえ排除・削減”できます。これらが

セキュアコーディングの知らない、知るつもりがない

この問題かなり根が深いと思われます。一つ事例を紹介します。

2年ほど前に「IPAのセキュアプログラミング講座は、ISO 27000やCERTのいうセキュアプログラミング/セキュアコーディングではない。セキュアコーディング最大のセキュリティ対策である入力バリデーションがないセキュアコーディングはあり得ない」とIPAに指摘するメールを送りました。

しばらくして、確かにその通りなので現在のセキュアプログラミング講座は削除する旨の返信を頂きました。2017年になって誤りがあった旧セキュアプログラミング講座は削除され、現在はCERT Top 10 Secure Coding Practicesをベースにしたセキュアプログラミング講座に一新されています。1

IT技術者であればよくご存じの通り、IPAと言えば情報セキュリティ対策を啓蒙する組織です。国際情報セキュリティ標準であるISO 27000の策定にも関わっているIPAでさえ、今年になるまでセキュアコーディングの原則1を広めていませんでした。

これは、IT専門家が「セキュアコーディングを知らない、知るつもりがない」の典型的な例と言えるでしょう。

※ IPAの標準規格を策定する部署と国内向けに情報セキュリティ対策啓蒙する部署は別だそうです。標準規格を策定している人達まで知らなかった、知るつもりがなかった、はさすがに無いはずです。

”セキュアコーディングではない設計”を”セキュアコーディング”だと勘違いしている

これは「セキュアコーディングの知らない、知るつもりがない」と深く関連していると思われます。

セキュアコーディングの第一の原則は、信頼境界で入力をバリデーションする、です。第七の原則(IPA版は第二の原則)は、出力を無害化する、です。ISO 27000(ISO 17799)は10年以上に渡ってセキュアコーディング原則1の実装と管理方法を具体的に記載してきました。

CERTセキュアコーディングに準拠したプログラムにするには、全ての原則を実装する必要があります。以下はPHPカンファレンス2017の講演資料ですが、セキュアコーディングの第一の原則は必要ない、とする内容になっています。

セキュアコーディング原則の第一番目を無視するコーディング/設計はセキュアコーディングに準拠したコーディング/設計とは言えません。

スライドで紹介しているように、現在あるほぼ全てアプリケーションはセキュアコーディング原則第一番目を実装せず、セキュアコーディングではありません。セキュアコーディングではない物から、セキュアコーディングを学ぶことはできません。

セキュアコーディングで求められる入力バリデーションとは?

セキュアコーディング原則1では、全ての入力をホワイトリスト型でバリデーションする、ことが求められています。

先日リリースされた2017年版OWASP TOP 10がを例に、入力をバリデーションで何をしなければならないのか紹介します。

2017年版OWASP TOP 10 A10はセキュアコーディング原則1を実装し

Establish effective monitoring and alerting such that suspicious
activities are detected and responded to in a timely fashion.
(疑わしい活動がタイムリーな形で検出され対応できる効果的なモニタリングと警告を確立する)

上記が達成できるシステムでないと脆弱なシステムである、としています。

検出すべき疑わしい活動には以下が含まれます。

• Penetration testing and scans by DAST tools (such as OWASP
ZAP) do not trigger alerts.
(OWASP ZAPなど、DASTツールによる侵入テストとスキャンが警告を発生させない)

※ OWASP ZAPはWebアプリに攻撃用の不正な入力を効率的に送信できる攻撃用プロキシアプリです。

攻撃用の不正な入力を検出できないと脆弱なシステムになります。

• The application is unable to detect, escalate, or alert for active
attacks in real time or near real time
(アプリケーションが現在進行中の攻撃を即時または即時に近い時間で検出、エスカレートまたは警告できない)

ZAPで簡単に生成できる攻撃用の不正な入力は、HTMLフォームの入力に限りません。HTTPヘッダー、クッキー、URLパラメーター、HTMLフォームには含まれない余計なパラメーターや改ざんされたパラメーターなども含まれます。

これらをアプリケーションの”どこで”、”どのように”検出し対応すべきでしょうか?

どこでどのように検出すべきか?の前に入力バリデーションとは何かOWASP Code Review Guide V2.0などの説明を知っておく必要があります。

7.6 Input Validation

Input validation is one of the most effective technical controls for application security. It can mitigate numerous vulnerabilities including cross-site scripting, various forms of injection, and some buffer overflows. Input validation is more than checking form field values.

All data from users needs to be considered entrusted. Remember one of the top rules of secure coding is “Don’t trust user input”. Always validate user data with the full knowledge of what your application is trying to accomplish.

Regular expressions can be used to validate user input, but the more complicated the regular express are the more chance it is not full proof and has errors for corner cases. Regular expressions are also very hard fro QA to test. Regular expressions may also make it hard for the code reviewer to do a good review of the regular expressions.

Data Validation

All external input to the system (and between systems/applications) should undergo input validation. The validation rules are defined by the business requirements for the application. If possible, an exact match validator should be implemented. Exact match only permits data that conforms to an expected value. A “Known good” approach (white-list), which is a little weaker, but more flexible, is common. Known good only permits characters/ASCII ranges defined within a white-list.

Such a range is defined by the business requirements of the input field. The other approaches to data validation are “known bad,” which is a black list of “bad characters”. This approach is not future proof and would need maintenance. “Encode bad” would be very weak, as it would simply encode characters considered “bad” to a format, which should not affect the functionality of the application.

Business Validation

Business validation is concerned with business logic. An understanding of the business logic is required prior to reviewing the code, which performs such logic. Business validation could be used to limit the value range or a transaction inputted by a user or reject input, which does not make too much business sense. Reviewing code for business validation can also include rounding errors or floating point issues which may give rise to issues such as integer overflows, which can dramatically damage the bottom line.

長いので要約だけにします。入力バリデーションにはData Validation(データバリデーション)Business Validation(ビジネスロジックのバリデーション)があります。この区別をしっかり理解している必要があります。

Data Validationは入力値のデータ形式をISO 27000が要求する方式でバリデーションします。データの論理的な正しさを検証する必要はありません。2形式だけで十分です。アプリケーションのData Validationはアプリケーションの信頼境界で行います。適切な場所はMVCモデルなら”コントローラー”です。

Business Validationはビジネスロジックとして、送信された日付が存在する日付か?ビジネスロジックとして正しい日付か?(例えば予約で過去の日付はあり得ない)などデータの論理的な妥当性をバリデーションします。適切な場所はMVCモデルなら”モデル”です。

まとめ

ブログを書いている時間が無くなったので、無理やりまとめます。追記すると思うのでもう少し詳しい解説に興味がある方は後日ご覧ください。

セキュアコーディングとセキュアコーディングが要求する基本的なソフトウェアセキュリティ設計(信頼境界での入力バリデーション)が全くと言ってよいほど普及していない原因は、IPAや著名なセキュリティ専門家が公開している(していた)資料から明らかではないでしょうか?

  • セキュアコーディングの知らない、知るつもりがない
  • ”セキュアコーディングではない設計”を”セキュアコーディング”だと勘違いしている
  • +”本当のセキュアコーディングでないモノ”を”セキュアコーディング”だと啓蒙している(していた)

「本来のセキュアコーディング」を理解すると、IPAや例に挙げたセキュリティ専門家以外にも多数のIT専門家が同じように「国際標準やセキュリティガイドラインに準拠しないセキュアコーディング」を信じていたこと、をIT業界に居る方なら体感できると思います。専門家や先輩開発者からおかしなモノでも「セキュアコーディングとはこうだ」と説明されると普通は「そうなのだろう」と信じてしまいます。

これでは多くの一般開発者が「本当のセキュアコーディング」を知らなくて、ほぼすべてのアプリケーションがセキュアコーディングになっていないのも当然だと思います。。。

 


  1. 2016年10月の改定ではCERT Top 10 Secure Coding Practicesは紹介されておらず、2017年6月の改定で追加されたように思います。前の版は参照できないようなので前の版(2016年10月版のURLをご存じの方、教えてください) 
  2. クライアントが送ってくることが可能なデータであることをバリデーションします。Data Validationでの論理的バリデーションは必要ありません。クライアントが存在する日付だけ送ってる、クライアントは過去の日付を送ってこない、といった条件があり簡単に検証できるのであれば「存在する日付」「未来の日付」である論理的バリデーションを行っても問題ありません。というより、可能であるならこういったバリデーションをコントローラーで行った方が良い場合も少なくないです。 

Comments

comments