2019年1月15日火曜日

CWE-20入門

サマリ

この記事の想定読者は、企業等の脆弱性ハンドリング担当者です。脆弱性情報にしばしば出てくるCWE-20の読み解き方を説明します。

追記(2024/11/26)

現在CWE-20の本家のサイトでは、Vulnerability Mapping: DISCOURAGED(脆弱性マッピング:非推奨)と表記されています。詳細を見ると、以下が記載されています。
Vulnerability Mapping Notes
Usage: DISCOURAGED (this CWE ID should not be used to map to real-world vulnerabilities)
Reason: Frequent Misuse
Rationale: CWE-20 is commonly misused in low-information vulnerability reports when lower-level CWEs could be used instead, or when more details about the vulnerability are available [REF-1287]. It is not useful for trend analysis. It is also a level-1 Class (i.e., a child of a Pillar).

試訳
使用法: 非推奨(このCWE IDを実際の脆弱性にマッピングするのは避けるべき)
理由: 頻繁な誤用
根拠:CWE-20は、低情報の脆弱性レポートにおいて、より詳細な情報が得られる場合や、より低レベルのCWEを使用できる場合にも誤って使用されることが多い。これは傾向分析に役立つものではない。また、レベル1クラス(すなわち、抽象度高い大分類クラス(意訳))でもある。
すなわち、本稿の後半で述べている私の主張は、CWE本家で追認されたことになります。
(追記終わり)

CWEとは

CWEはCommon Weakness Enumerationの略で、日本語では「共通脆弱性タイプ一覧」と訳されています。この訳からも分かるように、脆弱性をタイプ毎に分類しているものです。つまり、SQLインジェクション、XSS、バッファオーバーフロー等に、CWE-XXXという「分類番号」をふったものと考えるとわかりやすいでしょう。以下は、IPAが公表しているCWEの解説記事からの引用です。
1999年頃から米国政府の支援を受けた非営利団体のMITRE(*2)が中心となり仕様策定が行われ、2006年3月に最初の原案が公開されました。その後、40を超えるベンダーや研究機関が協力して仕様改善や内容拡充が行われ、2008年9月9日にCWEバージョン1.0が公開されました。
共通脆弱性タイプ一覧CWE概説:IPA 独立行政法人 情報処理推進機構 から引用
代表的なCWEは、この記事中の以下の図を見るとわかりやすいと思います。


CWEの特徴の一つは、上図から明らかなように、階層的な分類になっていることです。たとえば、インジェクションCWE-74の下の階層には、XSS、SQLインジェクション、OSコマンドインジェクションなどの著名な脆弱性がぶら下がっていて、これらがインジェクションという共通の脆弱性のタイプに属していることがわかります。

CWE-20とは

本稿のテーマCWE-20は、インジェクションも包含する大分類になっています。先程引用した図からCWE-20関連のみを抽出したものを以下に示します


前述のインジェクションに加えてパストラバーサルなども含まれていますね。すなわち、外部からの入力値に起因する脆弱性がCWE-20としてまとめられています。
それにしても、CWE-20は「不適切な入力確認」(Improper Input Validation)と説明されていますが、これらはバリデーションの問題でしょうか。
そうではありません。パストラバーサルはバリデーションで対策可能ですが、インジェクション系のXSSやSQLインジェクションがバリデーションにより対策できない(完全な対策にならない)ことは明らかです。なのに、どうして、CWE-20は「不適切な入力確認」なのでしょうか。その答えは、本家のCWE-20の解説中にあります。
Some people use "input validation" as a general term that covers many different neutralization techniques for ensuring that input is appropriate, such as filtering, canonicalization, and escaping. Others use the term in a more narrow context to simply mean "checking if an input conforms to expectations without changing it."

CWE - CWE-20: Improper Input Validation (3.2)より引用
私訳を以下に示します。
フィルタリングや正規化、エスケープなど、入力が適切であることを確実にするためのさまざまな無効化手法をカバーする包括的な用語として「入力検証(Input Validation)」を使用する人もいます。他の人達は、より狭い文脈、すなわち、単に「入力を変更することなく、期待される値であることを確認する」という意味でこの用語を用います。
ということで、Input Validationはエスケープやフィルタリングを含む包括的な用語として使われる場合があることがわかります。CWE-20のInput Validationはこちらの意味でしょう。そうでないと、SQLインジェクションやXSS等をカバーする理由を説明できません。

CWE-20は大分類のはずなのに、個別脆弱性がしばしばCWE-20とされる

ここまで、CWE-20は脆弱性の大分類と説明しましたが、現実には個別の脆弱性がCWE-20と分類されるケースが多くあります。以下は、JVN iPediaで、CWE-20かつCVSSv2で7.0以上の脆弱性を検索した結果です。


CWE-20が大分類だとすると、個別脆弱性がCWE-20に分類されるのはおかしいですね。上記はどのようなものなのでしょうか。そこで、以下、この日記で過去に紹介した脆弱性の中からCWE-20とされているものを2件紹介して、CWE-20の実態に迫ります。

CWE-20の例(1)CGI版PHPのRCE脆弱性CVE-2012-1823

以下の記事で紹介した脆弱性です。

CGI版PHPにリモートからスクリプト実行を許す脆弱性(CVE-2012-1823)

PHPがCGIモードで動いている場合のみですが、外部から任意スクリプト実行可能な凶悪な脆弱性でした。この脆弱性はCWE-20に分類されています。
この脆弱性の原因は、CGIモードの場合クエリ文字列にスペース区切りで指定した文字列がCGIプログラムのコマンドライン引数として指定される仕様を悪用して、PHPに -s や -d 等のオプションを指定できてしまうところにありました。
この脆弱性のPHPソースコード上の問題は、以下の記事が詳しいです。

CVE-2012-1823 CVE-2012-2311 PHPのCGIモードにおける脆弱性について

この記事にもあるように、脆弱性の根本原因は、CGIモードの場合不要なオプションパラメータの処理が存在すること自体にあります。したがって、脆弱性の対策は、不要なオプションパラメータの処理を除去することであり、入力バリデーションを追加することではありません。

CWE-20の例(2)Joomla!のRCE脆弱性CVE-2015-8562

以下の記事やスライドで紹介した脆弱性です。やはり、CWE-20と分類されています。

Joomla!の「ゼロデイコード実行脆弱性」はPHPの既知の脆弱性が原因
脆弱性は誰のせい? PHP、MySQL、Joomla! の責任やいかに | slideshare

この脆弱性に対する攻撃は、もはや芸術的と表現しても良いくらいの高度なものです。以下の3つのソフトウェアの脆弱性および好ましくない仕様を組み合わせています。詳しくは上記の記事を参照ください。

Joomla! : CVE-2015-8562
PHP : CVE-2015-6835
MySQL : utf8_general_ci 指定した列にutf8の4バイト形式の文字を追加すると、その文字以降が切り詰められる仕様

そして、私自身は、この攻撃の根本原因はCVE-2015-6835(CWE-416: Use After Freeに分類)と考えています。攻撃全体としては、安全でないデシリアライゼーション(CWE-502)に該当します。
Joomla! のCVE-2015-8562は何がいけなかったかというと、Joomla!はセッションストレージとしてMySQLを利用していて、その結果、PHPのシリアライズ後のセッション情報をMySQLに格納しているのに、シリアライズ結果がバイナリとなる点を十分に考慮しておらず、utf8_general_ciという型を使用していたところにあります。
Joomla!側の対処としては、緊急対処として攻撃経路となるUser-Agentその他のHTTPヘッダをセッションに格納することをやめ、根本対策としてシリアライズ後のセッション情報をBase64エンコードしてから格納するようにしています。やはり、入力バリデーションを追加したわけではありません。

CWE-20の現実の使われ方

上記で紹介した2つの脆弱性は、いずれも狭義のバリデーションが主原因ではないのに、CWE-20が割り当てられていました。これらは、適当なCWEがないので、「とりあえず外部入力が経路なのでCWE-20にしておこう」という感じでCWE-20があてられているものと推測します。脆弱性情報を見ていると、そのようなケースは多く見受けられます。
また、商用製品の脆弱性情報に多い例として、脆弱性があることは公表するが、その詳細は公表したくないケースなどで、脆弱性分類としてCWE-20がわりあてられるケースがあります。先に、JVN iPediaの検索結果を示しましたが、高危険度のCWE-20脆弱性の例の大半が商用製品であることからも、これは伺えます。
現に、CWE-20の解説には以下のように記載されています。
The "input validation" term is extremely common, but it is used in many different ways. In some cases its usage can obscure the real underlying weakness or otherwise hide chaining and composite relationships.
CWE - CWE-20: Improper Input Validation (3.2)より引用
日本語訳としてJVNの訳を以下に引用します。
「入力の妥当性チェック」という用語は極めて一般的ですが、用語の使い方は様々です。いくつかのケースでは、根本的な脆弱性を曖昧にするためや、関連した複雑な事象を隠すことを目的として使われます。
CWE-20 より引用
ということで、CWE-20が使われるケースの多くは、脆弱性公表側の怠慢や隠蔽意図によるケースが多く、悪意がないケースとしては「分類の難しいその他のケース」ということになるかと思います。

まとめ

CWE-20について解説しました。本来、CWE-20は脆弱性パターンの大分類として取り扱うべきと考えますが、現実にはCWE-20とすべきでない局面でもCWE-20が濫用される傾向があります。私は、CWE-20の濫用は正確な脆弱性情報流通の上では有害だと考えています。
もし読者が、脆弱性情報中にCWE-20と記載されているのを見かけたら、「CWE-20では何もわからないではないか」と舌打ちしつつも、そうせざるを得なかった背景についても想いを馳せると、その脆弱性に対する関心が一層高まるのではないでしょうか。

フォロワー

ブログ アーカイブ