OWASPに対して失礼な誤解 – 入力バリデーションは重要なセキュリティ対策
OWASPに対して大変失礼な誤解をしている意見を見かけたのでブログに書いておきます。
OWASPは「入力バリデーション」とても重要な「セキュリティ対策」として考えていますが、OWASP的にはセキュリティ対策ではない、少なくとも重要なセキュリティ対策ではない、というとんでもない誤解はOWASPに対して大変失礼な誤解と言えます。
OWASPに対して大変失礼な誤解をしている意見を見かけたのでブログに書いておきます。
OWASPは「入力バリデーション」とても重要な「セキュリティ対策」として考えていますが、OWASP的にはセキュリティ対策ではない、少なくとも重要なセキュリティ対策ではない、というとんでもない誤解はOWASPに対して大変失礼な誤解と言えます。
PHPには他の言語と同様に様々な制限があります。まとまった資料が見つからなかったのでまとめておきます。PHPの制限と言っても実行時間の制限のようにマニュアルに記載されているINI設定などは記載していません。
デフォルト文字エンコーディング設定の仕様変更はPHP 5.6リリースの際に私が行った変更ですが、ブログで紹介していなかったような気がするので紹介します。PHP 5.5以下のmbstring正規表現デフォルト文字エンコーディングは”EUC-JP”でした。
一応、RFCには
と書いているのですが、これだけではmb_eregなどのデフォルト文字エンコーディングが変わっている事に気が付かない方も多い(気が付かない方が多い?)と思います。
一文字でも意味がある文字があるとインジェクション攻撃が可能な場合が多いです。正規表現も例外ではありません。
「黒い」セキュリティとはブラックリスト型セキュリティのことです。
ブラックリスト型セキュリティとは「ブラックリスト型対策でセキュリティを維持しよう」とする概念です。セキュリティ対策では、ブラックリスト型対策はできる限り使わず、可能な限りホワイトリスト型対策を使う、が基本です。しかし、ブラックリスト型の「黒いセキュリティ」対策が理想的な対策である、と考えている人が少くないようです。
「黒いセキュリティ」に頼ったITセキュリティは基本的に捨て去るべきです。
セキュアコーディング/セキュアプログラミングにおける最も重要なセキュリティ対策は「入力バリデーション」です。国際標準ではセキュリティ対策か否かは「リスクの変化」によって決り、※多くのセキュリティ専門家が「入力バリデーションをNo1のセキュリティ対策である」と結論づけています。(※ 対策の目的が何か?などの主観に基く評価はセキュリティ対策か否か、を決める指標ではありません)
どういう論理なのかは全く理解できないのですが、これに異論を唱える方も居るようです。実際のセキュアコーディング/セキュアプログラミングのガイドラインなどがどうなっているのか?紹介します。
このブログを継続して読んでいる方にはただの繰り返しなので読み飛ばしてください。そもそもセキュアコーディング/セキュアプログラミングとは何か?は過去のブログをご覧ください。
セキュアなアプリケーションのアーキテクチャの基本は既に書きました。基本は既に書いた通りですが、多少異るアプローチもあります。今回はそれを解説します。タイトルに含まれているsandbox化がキーワードです。
世の中には仕様としてセキュリティを考慮していないWebアプリも多くあります。特に開発環境では多いのではないでしょうか?こういったアプリも安全に使う為には少しだけ工夫が必要です。本来、セキュリティを考慮しておいた方が良いWebアプリであっても、セキュリティが考慮されていない場合でもこの方法は利用できます。
セキュアなアプリケーションには共通したアーキテクチャがあります。基本的には防御的プログラミング(セキュアプログラミング)を行い、防御的プログラミングのテクニックの1つである契約プログラミングを実践したアーキテクチャがセキュアなアーキテクチャです。
アプリケーションのセキュリティ問題のほとんどはインジェクション問題です。インジェクション問題以外にもセキュリティ問題はありますが、ここではインジェクション問題のみを考慮します。
記事を探すことができなかったのですが、少し前に元記事が英語で日本語訳された記事に「セキュアプログラミング・コーディングはハイプ(誇大な宣伝)である」とする記事がありました。これには全く賛同できません。
なぜセキュアプログラミング”だけ”でセキュアなプログラムが作らないのか?理由を考えてみたいと思います。
PHPのmt_rand関数のtwistマクロに一文字タイポがあり、修正されたのですが
http://git.php.net/?p=php-src.git;a=commitdiff;h=a0724d30817600540946b41e40f4cfc2a0c30f80
でリバートされてしまいました。
PHP 7.1からMT randのコードが修正されています。ユーザーコード(PHPスクリプト)からはアルゴリズムは選べません。Cモジュールの場合、旧アルゴリズムと修正済アルゴリズムから選択できるようになっています。
この他にもPHPのmt_rand()実装の場合、本来MT randは2^19937の状態を取り得るのですが、PHPはたったの2^32の状態でしか初期化できません。つまり、MT randアルゴリズムに較べて2^19902くらいPHPのmt_rand()は初期値は弱いことになります。(=比較にならないほどPHPのmt_rand()は予測し易い)
セキュアなプログラミングには基本的な考え方があります。それ守ることによりセキュアなプログラムを作ることができます。基本的な考え方を無視または意識しないでセキュアなプログラミングを目指しても遠回りだったり、漏れが生まれたりします。基本的な考え方を無視・意識しないでセキュアなプログラミングを行おうとしても無理があります。
ここで紹介するのは私の考えであり、どこかで標準化されている物ではありません。しかし、基礎からまとめると概ね同じような物になると思います。
PHPの性能はバイトコードキャッシュにより数倍向上するのですが、久しぶりにopcacheをキーワードに検索してみると「それほど効果がない」と誤った評価をしているページもあったので、Opcacheによりどのくらい速くなるか簡単なベンチマークをします。
マイナンバーのチェックデジットを確認する必要があったのでPHP関数を作りました。