入力バリデーションに「エスケープやフィルタリングが含まれる」とする驚くべき解説

(Last Updated On: 2021年12月15日)

標準的な入力バリデーションに「エスケープやフィルタリングが含まれる」とする驚くべき解説があります。そのような入力バリデーションを定義した標準的なセキュリティガイドライン/規格は見た事がありません。標準的な入力バリデーションでは何をすべし、とされているのか紹介します。

TLDR; 無駄な議論は終わり(追記)

普通の英文読解力があればCWE-20が意図する入力バリデーションの意味を間違える事は無いはずですが、誤解や曲解、自分勝手な解釈をする人が多かったのでしょう。MITREがCWE-20のTerminologyに一文を追加し、入力バリデーションにはエスケープやフィルタリングなどは含まれない、と誰が読んでも間違えないようにしました。詳しくは以下のブログをご覧ください。

CWE-20やセキュアコーディングの入力バリデーションとは「データの改変などを一切含まないデータ形式の妥当性検証」を指します。エスケープやフィルタリングは入力バリデーションではありません。

15年以上も見かける度に間違いを指摘し続けているのですが、それ以上の勢いで間違いを吹聴している人がいます。IPAまでセキュアコーディングを理解しておらず出鱈目なセキュリティガイドラインを公開しています。ソフトウェアエンジニアリング・コンピュータサイエンスをやっているハズのIPAが、自身が啓蒙しているはずセキュアコーディングの第一原則(入力バリデーション)の解説を間違えているのは致命的です。

問題の解説

とあるセキュリティ専門家のブログに書かれていました。CWE-20(Improper Input Validation)は不適切な入力バリデーション脆弱性です。

CWE – CWE-20: Improper Input Validation (3.2)より引用
私訳を以下に示します。

フィルタリングや正規化、エスケープなど、入力が適切であることを確実にするためのさまざまな無効化手法をカバーする包括的な用語として「入力検証(Input Validation)」を使用する人もいます。他の人達は、より狭い文脈、すなわち、単に「入力を変更することなく、期待される値であることを確認する」という意味でこの用語を用います。


ということで、Input Validationはエスケープやフィルタリングを含む包括的な用語として使われる場合があることがわかります。CWE-20のInput Validationはこちらの意味でしょう。そうでないと、SQLインジェクションやXSS等をカバーする理由を説明できません。

引用されている文はCWE-20の最後に記載さている”備考”(Notes)に”用語”(Glossary)の文です。これは、CWE-20の定義とは異なる用語の使い方をする人達も居ることに対する注意喚起です。

詳しくは おかしなCWE-20の読み解き方(CWE-20入門) を参照ください。

※ CWE-20(不適切な入力バリデーション)の対策/定義/要求事項はCWE-20の本文に記載されています。”備考の用語”はそれ以外の使われ方(CWE-20的には誤用)の解説です。

標準的な入力バリデーション

国際情報セキュリティ標準、MITRE(CWE)がどのように入力バリデーションをすべきとしているか紹介します。

大前提/原則として入力バリデーションは次のように行う物であることに留意してください。

  • ホワイトリスト型でチェックする
    • 適合しない入力は拒否する
  • 形式的バリデーションと論理的バリデーションの2種類があり、多層構造でバリデーションする
    • 「入力ミス」は形式的バリデーションでは妥当な入力であり、論理的(ビジネスロジック的)バリデーションで入力エラーとして処理する。入力データは大別して3種類しかない。
    • 妥当でない入力は有害でしかない。従ってできる限り早くバリデーションする。(リスク管理基本原則のフェイルファースト

国際情報セキュリティ標準(ISO 27000)では以下のように定義していました。

入力データの妥当性確認(10.2.1)
業務システムに入力されるデータは、正確で適切である事を確実にするために、その妥当性を確認することが望ましい。業務取引処理(transaction)、常備データ(名前、住所、信用限度、顧客参照番号)及びパラメタ(売価、通貨レート、税率)の入力を検査することが望ましい。次の管理策を考慮することが望ましい。
次の誤りを検出するための二重入力又はその他の入力検査。

* 範囲外の値。
* データフィールド中の無効文字。
* 入力漏れデータ又は不完全なデータ。
* データ量の上限及び下限からの超過。
* 認可されていない又は一貫しないデータ。

その妥当性及び完全性を確認するために重要なフィールド又はデータファイルの内容の定期的見直し。

入力データに認可されていない変更があるかどうかについての紙に印刷した入力文書の点検(入力文書に対する変更はすべて、認可を得ることをが望ましい。)。

妥当性確認の誤りに対応する手順。

入力データのもっともらしさを試験する手順。

データ入力仮定にかかわっているすべての要因の責任を明確に定めること。

現在のISO 27000ではセキュアプログラミング技術は体系的にまとめられ、広く普及したとし「セキュアプログラミング技術を採用する」と簡潔に記載されています。上記の具体的な入力バリデーション方法は2000年版(初版 – ISO 27000の前身のISO 17799)から2013年版で「セキュアプログラミング技術を採用する」と簡潔な記述に変更されるまで記載されていました。

ISO 27000の入力バリデーションに「エスケープやフィルタリング」は含まれません。

CWEを管理しているMITREは脆弱性対策ガイドラインとしてCWE/SANS TOP 25を2011年から公開しています。その中で「恐ろしく効果的(怪物的な)セキュリティ対策」(Monster Mitigations – Mitigation(緩和策)はISO 27000の定義でセキュリティ対策(リスク管理策)の一つとして定義されている)として次のようなバリデーションが「標準入力バリデーション」としています。

全ての入力に対して標準入力バリデーション機構を利用する:
* 長さ
* 入力種別
* 文法(※ 形式)
* 少すぎる/多すぎる入力
* 関連するデータの整合性
* ビジネスルール

CWE/SANS TOP 25は解説文書なので簡潔にCWE-20を紹介しています。わざわざ”標準”(Standard)入力バリデーション、と”標準”を付けて他の意味での使われ方との差別化の意図も見えます。入力のサニタイズ(有害な入力の無害化/フィルタリング)を入力バリデーションと勘違いしている人が少なくないことがその理由と思われます。

CWE/SANS TOP 25の入力バリデーションに「エスケープやフィルタリング」は含まれません。

それどころか、多すぎる入力は拒否すべきバリデーション対象としています。フィルタリングするとダメだ、としていることが明白に分かります

CWE-20の「実装」(Implementation)では以下のように記載しています。長いですが、英文のまま引用します。

Assume all input is malicious. Use an “accept known good” input validation strategy, i.e., use a whitelist of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.

When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, “boat” may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as “red” or “blue.”

Do not rely exclusively on looking for malicious or malformed inputs (i.e., do not rely on a blacklist). A blacklist is likely to miss at least one undesirable input, especially if the code’s environment changes. This can give attackers enough room to bypass the intended validation. However, blacklists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.

When your application combines data from multiple sources, perform the validation after the sources have been combined. The individual data elements may pass the validation step but violate the intended restrictions after they have been combined.

Be especially careful to validate all input when invoking code that crosses language boundaries, such as from an interpreted language to native code. This could create an unexpected interaction between the language boundaries. Ensure that you are not violating any of the expectations of the language with which you are interfacing. For example, even though Java may not be susceptible to buffer overflows, providing a large argument in a call to native code might trigger an overflow.

Directly convert your input type into the expected data type, such as using a conversion function that translates a string into a number. After converting to the expected data type, ensure that the input’s values fall within the expected range of allowable values and that multi-field consistencies are maintained.

Inputs should be decoded and canonicalized to the application’s current internal representation before being validated (CWE-180CWE-181). Make sure that your application does not inadvertently decode the same input twice (CWE-174). Such errors could be used to bypass whitelist schemes by introducing dangerous inputs after they have been checked. Use libraries such as the OWASP ESAPI Canonicalization control.Consider performing repeated canonicalization until your input does not change any more. This will avoid double-decoding and similar scenarios, but it might inadvertently modify inputs that are allowed to contain properly-encoded dangerous content.

When exchanging data between components, ensure that both components are using the same character encoding. Ensure that the proper encoding is applied at each interface. Explicitly set the encoding you are using whenever the protocol allows you to do so.

入力バリデーションの前にデータの正規化が必要である、適切な文字エンコーディングを明示的に利用する、などとしていますが「エスケープする」や「フィルタリングする」などとは記載されていません。

CWE-20の入力バリデーションに「エスケープやフィルタリング」は含まれません。

CERTやOWASPがどのように入力バリデーションを定義/解説しているのか、も書こうと思いましたが長くなりすぎるので止めました。当然ですが、入力バリデーションに「エスケープやフィルタリング」は含まれません。 反対にOWASP TOP 10 A10:2017では「無効な入力の無視(当然、フィルタリングも)はアプリケーション脆弱性である」と明示的に解説しています。

※ CERT Secure Coding Standard(Java/PERL/Android)にはIDS(Input Validation and Data Sanitization)という項目があり、入力データバリデーションと出力データ無害化が一つの項目で解説しています。これは「データ」を安全に取り扱う項目としてまとめているからです。しかし、項目としてまとめてあってもセキュアコーディング原則に書かれている通り、原則”および”ソフトウェアの構造”として入力データ対策と出力データ対策は別のモノ、です。

標準的なセキュリティガイドラインやセキュリティ規格で、入力バリデーションに「エスケープやフィルタリング」が含まれる、とした物を見た事がありません。

無いはずですが、もし在るのであれば参考の為に見てみたいです。

徳丸さんは、ブラックリスト型対策もホワイトリスト型対策と変わらない、入力バリデーションはセキュリティ対策ではない/重要ではない、信頼境界は重要ではない/役立たない、SQLインジェクション対策はプリペアードクエリ/プレイスホルダだけで対策できる、と様々な驚きの解説をしてきました。

入力バリデーションに「エスケープやフィルタリング」が含まれる(NEW)が追加されたので、メモとしてのブログでした。

参考:

科学的なセキュリティ対策を提唱するCERT、MITRE、ISO、NISTなどでは長年、入力バリデーションを一番目のソフトウェアセキュリティ対策と位置づけてきました。

  • ソフトウェアは妥当な入力以外では絶対に正しく動作しない

というシンプルで解りやすい不変の動作原理があるからです。(※ 「入力ミス」は”形式的”に妥当な入力です。バリデーションには”形式”と”ロジック”の2種類があります。混乱しているケースをよく見かけます。)

2021年5月28日追加: JVNのCWE-20日本語訳が意味不明な改悪をしています。この間違いはJVN(=IPA)が出所だと言えるようです。あまりに酷い間違いなのでJVNに連絡して修正するように連絡しました。

PHPの馬鹿馬鹿しい入力対策 – magic quote

PHPの黒歴史と言える過去の機能の一つにmagic quote(マジッククオート)がありました。勿論、今のPHPにはありません。

magic quote – 入力データに対して自動的かつ無条件にスラッシュ(/)を追加しエスケープする機能。しかも、デフォルトで。

昔はPHPのダメさを象徴する機能として有名でした。個人的には、というよりほぼ全てのPHPユーザーが「なんて馬鹿げた機能だ」と思っていたはずです。

2000年頃からPHPを使って2003年からPHP開発者をしていますが、当時からPHP本体の開発者であっても「magic quoteによるエスケープが正しいセキュリティ機能だ!」と胸をはって主張する人は居ませんでした。知る限りではエスケープを入力対策(≒入力バリデーション)として使った例はほとんどないですが、このPHPの黒歴史機能はその代表例です。

入力対策(=入力バリデーション)としてエスケープするのは明らかなアンチプラクティスで行てはならないダメな対策です。

magic quoteにより自動的に入力データをaddslashes()でエスケープしても、

  • 他のエスケープが必要なSQLやHTMLなどのコンテクストにはセキュリティ対策として無意味
  • 単純なテキストとして入力データを出力したい場合、アンエスケープしないと正しく出力できない
  • データによってはエスケープするとデータが壊れ、それが攻撃に利用できる。例:SJIS

上記のようにセキュリティ対策として無意味/無駄であるだけはなく、別のセキュリティ問題を生むダメな仕様がmagic quoteでした。入力対策はエスケープやフィルタリングするのではなく、バリデーションが必要です。

今になって「エスケープも入力バリデーションに含まれる!!」といった主張を耳にするとは思いもよりませんでした。

投稿者: yohgaki