(Last Updated On: 2018年8月8日)

このブログは、IPAは基礎的誤りを明示し、正しい原則を開発者に啓蒙すべき、の「追加の情報」として書いた物を別エントリとしてまとめた物です。

CERTセキュアコーディング

  • 入力バリデーション(原則1)
  • ”セキュアコーディング標準”による安全なロジック処理(+具体的な入力/出力処理)※ 原則10 「セキュアコーディング標準を採用する」=自ら作るモノ
  • 出力の無害化(原則7)※ IPA版は原則2

の3つが1つのセットとして成り立ちます。これ以外はセキュアコーディングではありません。

入力、ロジック、出力、これら全てにバリデーションが必要です。

参考: コンピュータは数値さえ正確に扱えない

全ての入力をバリデーション

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

Webアプリの場合、でブラウザから送られてくる「全ての入力」には

  • クエリパラメーター – PHPなら$_GET
  • Formパラメーター – PHPなら$_POST、$_FILES、php://input
  • HTTPヘッダー – PHPなら$_COOKIE、$_SERVER、apache_request_headers()
  • 環境変数 – PHPなら$_ENV

が含まれます。

他に通信するプログラム、例えば外部のWebサービスから情報を取得する場合、それらから得られるデータ全てがバリデーション対象になります。

入力バリデーションの方法

基本的なバリデーション方法についてはISO 27000の入力データ妥当性検証を採用すると良いです。余計なデータ、足りないデータがある場合もバリデーションエラーである点に注意してください。

参考: ISO 27000の入力データ妥当性確認

まず大前提として、バリデーションに失敗したデータが1つでもある場合は処理を停止しなければなりません。バリデーションに失敗するデータは仕様上あり得ない不正なデータであり、アプリケーションにとって有害で無益だからです。

参考:コンピュータは数値さえ正確に扱えない

参考:入力値は3種類しかない

OWASP TOP 10の要求事項

まず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アプリに攻撃用の不正な入力を効率的に送信できる攻撃用プロキシアプリです。DAST – Dynamic Application Security Testing、動的アプリケーションセキュリティテスト

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

• 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では「今のWebアプリは入り口対策は全くと行ってよいほどない」と考えています。

以前からOWASP TOP 10は「インジェクション対策として入力バリデーションを要求」していました。2017年版OWASP TOP 10 からバリデーションに対する要求が更に強化されました。

単にバリデーションして無効なリクエストを廃棄するだけでは不十分です。不正なデータでバリデーションエラーになるリクエストに対して以下を行います。

  • 記録 – 後で利用可能な形で記録
  • 報告 – バリデーションエラーになるリクエストは攻撃かバグ
  • 対応 – 自動的に対応可能な場合は対応、セッション破棄、IPブロックなど

OWASP Code Review Guideの要求事項

どこでどのように検出すべきか?の前にまず、入力バリデーションとは何か?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.
入力バリデーションは最も効果的なアプリケーションセキュリティの1つである。入力バリデーションな数えきれない脆弱性、クロスサイトスクリプティング、様々な形式のインジェクション、そしてバッファーオーバーフロー攻撃を緩和できます。入力バリデーションとは単なるフィールド値のチェックではないです。)

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.
(全てのユーザーからのデータは信頼可能でなければならない。セキュアコーディングの最大のルールの1つ「ユーザー入力を信頼するな」を思い出してください。貴方のアプリケーションがユーザーデータで何をしようといているか、全ての知識を使い、常にユーザーデータをバリデーションしなければならない。)

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 from QA to test. Regular expressions may also make it hard for the code reviewer to do a good review of the regular expressions.
(正規表現はユーザー入力をバリデーションする為に利用できる。しかし、より複雑な正規表現はより多くの検証不足(訳注:バグ)とエッジケースの問題を持つ可能性が高くなる。正規表現はQAからテストすることが非常に困難でもある。正規表現はコードレビューワーが質の高い正規表現のレビューを困難にする。)訳注:要するに正規表現はリスクがある、多用するな、です。

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.
システムに対する全ての外部からの入力(加えて、システム/アプリケーション間の入出力)は入力バリデーションしなければならない。バリデーションルールはアプリケーションのビジネス要求で定義される。可能であるなら厳格に一致するバリデーターを実装しなければならない。厳格な一致は期待している値のデータだけを許可することを保証できる。”良いモノ”を許可するアプローチ(ホワイトリスト)は少し弱いがより柔軟で一般的である。”良いモノ”を許可するアプローチはホワイトリストで定義された文字/ASCIIの範囲のみを許可する。)

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(ビジネスロジックのバリデーション)があります。この区別をしっかり理解している必要があります。

これに加えて出力時にもバリデーションが必要です。

バリデーションをどこで行うか?

一番重要なアプリケーションの入力バリデーションは「アプリケーションの信頼境界」で行います。出力バリデーションを行う場合も「アプリケーションの信頼境界」で行います。

参考:エンジニア必須の概念 – 契約による設計と信頼境界線

入力バリデーションを行う適切な場所はMVCモデルなら基本的には”コントローラー”です。モデル内で外部サービスからデータを取得する場合はモデルでも入力バリデーションを行います。

ロジックバリデーションを行う適切な箇所はMVCモデルなら、当然ですが、”モデル”です。

出力バリデーションを行う適切な箇所はMVCモデルなら、基本的には”モデル”です。SQLクエリならクエリを作る時、HTMLならHTMLを作る時(ビューの直前、HTMLヘルパーの中など)にバリデーションを行います。出力対策はバリデーションだけで行なえません。エスケープ/API/バリデーションを適切に使い分けます。

参考:出力対策の3原則+1原則

入力、ロジック、出力のバリデーションはそれぞれ役割が異なります。何れかをすれば良い物ではありません。

  • 入力: データの形式、数などの妥当性を検証
  • ロジック: 論理的な妥当性を検証
  • 出力: フェイルセーフ。万が一、おかしなデータがあった場合に対応

参考:バリデーションには3種類のバリデーションがある

 

投稿者: yohgaki