出力時のフェイルセーフ対策が最も重要なセキュリティ対策であるはずがない

(Last Updated On: 2021年6月3日)

コンピューターサイエンス・システムエンジニアリングに基づくソフトウェアセキュリティ対策は論理的に構築されており問題ないです。しかし、一般に広まっているソフトウェアセキュリティ対策には出鱈目が普通にまかり通っています。

その最たる例はCWE-20の出鱈目な紹介や解釈です。

Terminology

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.

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 uses this more narrow interpretation.

太字部分の訳

他の人々はより狭いコンテクストで”変更しなくても入力が期待に沿うモノかチェックすること”の意味で使用する。CWEはこの狭い意味の解釈を採用している。

このように現在の本家CWE-20の用語補足では「”変更しなくても入力が期待に沿うモノかチェックすること”の意味で使用」と明記されていますが、CWE-20にエスケープやフィルタリングが含まれる、とする驚くべき解説をする”セキュリティ専門家”が居たりします。(普通は「CWEはこの狭い意味の解釈を採用している」と注釈なくてもそれ以前に解説の文意で判る)

出力時のフェイルセーフ対策が最も重要なセキュリティ対策であるはずがない

全てのプログラムの基本構造は以下の図のようになっています。

中には内部の状態を変更し、明示的な出力・戻り値を持たないプログラム・コードも在ったりしますが、内部状態の変更は出力の一種と考えることができます。内部状態の変更も出力・戻り値もないプログラム・コードは何もしないデッドコードでただの無駄で不必要なコードです。従って、有用なプログラム・コードは必ず上記のような基本構造をもっています。

出力無害化(=エスケープ処理やAPIによるパラメーター分離)はセキュリティ対策の基本中の基本で重要な対策ですが、必須でない出力無害化はフェイルセーフ対策です。

例えば、$id が整数型、$strが文字列、$tableが文字列で全てユーザー入力であり

SELECT id, str FROM tbl WHERE id = $id and str LIKE ‘$str’;

といったSQLクエリを実行する場合、$idの安全性はバリデーションで保証できるので sql_escape($id) といった出力無害化処理はフェイルセーフ対策、escape_sql($str)は必須の出力無害化処理です。そもそも整数型の$idに “1; DROP tbl –” のような文字列データが渡されることがそもそもの間違いです。$idが整数であることを予め確認しているのが正しい処理です。

CWE-20対策(入力データバリデーション)を徹底して行った上で、全ての出力データを独立した処理として無害化するのがセキュアなプログラムです。

SQL文の識別子(カラム名、テーブル名など)はエスケープしただけでは無害化できません。$col, $tbl, $orderがユーザー入力である場合、で

SELECT $col FROM $tbl ORDER BY $order;

といったクエリがある場合は識別子である$col, $tbl, $orderはホワイトリスト型で入力バリデーションしていないと安全に実行できません

最も重要なセキュリティ対策

CERT Top 10 Secure Coding PracticesやISO 27000:2013(以前)、CWE/SAN TOP 25:2011に従うと、入力データバリデーションが最も重要なセキュアコーディング・セキュアプログラミングの要素であると定義されています。

プログラムが処理可能な妥当なデータだけ処理する、これが正しく動作するプログラムの為の絶対要素であるからです。

出力の無害化も必要ですが、プログラムが正しく動作するための絶対的な要素、ではないです。出力の無害化だけに注力しても何時まで経っても正しく動作する(=安全に動作する)プログラムは作れません。

今の一般に言われるWebアプリセキュリティ対策は「出力対策に偏重、入力バリデーションはスカスカ」になっています。

JVNがCWE-20を意図的に誤訳(用語解説の位置を改悪)したこともこのような現状に一役買っていると言えるでしょう。一番大切な要素を意図的誤訳で台無しにしてるJVN(IPA)の責任は重大であると言えるでしょう。

セキュアコーディング・セキュアプログラミングの絶対原則

どんなプログラム・コードでも絶対に適用すべき原則は

  • 全ての入力の妥当性が検証されていること – 入力バリデーション
  • 失敗するモノはできる限り早く失敗させること – フェイルファースト

この2つは絶対的な原則です。これを実施しなくても良いプログラムは例外です。

入力バリデーションの実施原則はCERT, ISO, MITRE, OWASP, IPAなどがガイドラインを公開しています。妥当な入力でしかプログラムは正しく動作できない。これはプログラムの動作原理なので考え方や何かで変わるモノではありません。

フェイルファースト原則は当たり前過ぎて誰も定義していませんが、プログラムを作り始めた時に「エラー処理は最初に行うモノ」と習った事があると思います。習わなくても、エラー・不正になるデータを最後の最後まで何とか処理してしまうプログラムが正しくないことは開発者であれば解ると思います。

投稿者: yohgaki