徳丸先生に聞いた!メモリエラーは脆弱性?脆弱性の定義とは?


先日とある開発の中でお客様より、特定の操作をすることでPHPのメモリエラーになる。 この操作ができるということは脆弱な問題があると指摘いただきました。
(阿部の思考)
特定の操作を行うことで、メモリエラーになることは確かなのですが、果たしてそれが脆弱性なのかは疑問でした。
個人的に脆弱性とは下記だと考えていました。
- 特定の操作を行うことで情報が流出する。
- 悪意のあるコードをしかけられる構造になっている。(結果、フィッシングサイトへ誘導する。またはウイルスに感染させる。)(データ改ざん等)
- メール送信等の踏み台にされる。
メモリエラーが脆弱性なのかに関しては疑問でしたので、セキュリティ界隈で権威のある徳丸先生にお伺いしてみようと、お声がけさせていただいたところ快くお引き受けいただいたので今回記事にしてみました。
(左:徳丸先生、右:阿部)
徳丸先生とは
通称:徳丸本(体系的に学ぶ安全なWebアプリケーションの作り方)の著者で、セキュリティ界隈のイベントに多数登壇している、セキュリティ界隈の重鎮です。
脆弱性とは
まず初めに脆弱性とは何なのかをWikipedia先生に聞いてみました。
脆弱性(ぜいじゃくせい、英: vulnerability)とは、情報セキュリティ・サイバーセキュリティの用語で、コンピュータに存在する情報セキュリティ上の欠陥をいう。 セキュリティホールとも呼ばれる。
- Wipipediaより引用
(阿部)
Wikipediaによると、「コンピュータに存在する情報セキュリティ上の欠陥」とのことですが、情報セキュリティ上の欠陥とは何でしょうか。うーん、よく分からないですね...笑
早速ですが、徳丸先生にお伺いしてみましょう。
徳丸先生のご意見、脆弱性とは
(徳丸先生より)
脆弱性についての定義は複数あり、よく使われる定義がセキュリティのCIAです。これらが損なわれる事象を「脆弱性がある」と定義しています。
私(徳丸)としてはこれらのCIAが損なわれる事象のうち全てを脆弱性と捉えるのではなく「悪用可能なもの」を「脆弱性」として捉えています。
セキュリティのCIA
(徳丸先生より)
機密性(Confidentiality):
情報が許可された者だけにアクセスされること。
脆弱性の悪用例:攻撃者は不正に情報にアクセスし、機密情報が漏洩する
完全性(Integrity):
情報が正確であり、改ざんされていないことを保証。
脆弱性の悪用例:攻撃者はデータを変更したり、偽の情報を挿入したりすることが可能
可用性(Availability):
情報やシステムが必要なときに利用可能であることを保証。
脆弱性の悪用例:サービス拒否攻撃(DoS攻撃)などによってシステムがダウンし、正当なユーザーが情報にアクセスできなくなる
(阿部)
非常に分かりやすい説明ですね。
可用性に関しても脆弱性に値するということは、今回(お客様に指摘された事項)のメモリエラーも脆弱性に値するのでしょうか。
具体的に深堀していきたいと思います。
PHPメモリエラーが脆弱性なのか
(徳丸先生より)
全てのメモリエラーが脆弱性とは言えません。
例えば、巨大なサイズのファイルをPOSTでデータ送信した場合にメモリエラーになってしまいます。
この挙動は、エラーにすることによって過剰なメモリーを利用することを防いだわけですのでむしろ正しい制御といえ、脆弱性ではありません。
脆弱性に当たるものは少量のデータを送っているが内部で巨大なメモリーを利用してしまうものは脆弱性と言えます。
有名なエラーとしてはApache Killerなどがあります。
(阿部)
Apache Killerなど、詳しくは徳丸先生のブログに掲載されていますので参照ください。
今回(お客様からの指摘事項)は特定の操作をすることによって、メモリエラーとなる。その特定の操作が何かという点で、脆弱性か、そうでないかが変わってくるということですね。
今回指摘された事象
それでは、今回お客様から指摘された事項について、モチヤサイトを例に再現して見ていきましょう。
モチヤサイト上部にある検索ボックスに、テキストを入力し、エンターもしくはボタンをクリックします。
(例)https://www.mochiya.ad.jp/blog/search?keys=Drupal
入力した値がURLのGETメソッドにより、サーバーサイドに入力した値を渡します。 「Drupal」という値を受け取った後は、サーバーサイド側で、データベースに「Drupal」というキーワードが無いか問い合わせを行い、結果を返答します。
今回お客様から指摘された件は、URLの keys=Drupalを、keys[]=Drupal とすると、メモリエラーが起きていました。 モチヤサイトで同様のことを行うと「クライアントエラー」とエラー表示されます。 https://www.mochiya.ad.jp/blog/search?keys[]=モチヤ
今回お客様から指摘された開発途中のシステムに対して、同じ操作を行うとメモリエラーとなりました。このメモリエラーになる点について脆弱性だと指摘を受けました。
お客様から脆弱性と指摘された理由
通常、keys=文字列でサーバーに問い合わせを行った場合、サーバー側ではkeysというString型の変数(単一の値を入れる箱)に文字列の代入を行います。 今回 keys[]=文字列とすると、keysという配列(複数の文字列を入れる箱)と、システムが認識を行います。この想定されていない型を指定したときにエラーとなっていました。
予期しない変数の型指定や、キーの入力があった場合のことを考慮して、本来Webアプリケーションは、決められたキーと型以外を受け取ったらエラーを出力したほうが良いというのが、お客様からの指摘理由とのことです。
(阿部の考察)
本当にWebアプリケーションとして、受け取るキーを全て指定していく必要があるのでしょうか。不明なキーが来たときは、何もプログラムが動作をしないということで、良いのではないかと考えています。(Drupalではそのような書き方をしない)
なお受け取った値は、Drupalの受け取り関数により受け取っています。そのため適切なサニタイズは行われており、インジェクションに関する脆弱性は無いというのが前提です。
受け取るクエリのKey名と、型の指定について
(徳丸先生より)
まず、受け取るクエリのKey名と型を指定した方が良いかに関しては、必ずしなくても良いが、保険的にした方が良いと言えるでしょう。
理由は、かなり稀ではありますが、過去に似たような手法で脆弱性が存在したフレームワークや、アプリケーションがあったからです。
詳しくは「O/RマッパーやSQLジェネレータとSQLインジェ クション(pdf)」を参照ください。
今回の事象について
(徳丸先生より)
今回の事象は、特定の操作によりプログラム内部で無限ループに入り、結果メモリエラーとなるということで、少量のクエリを投げたことによって、プログラムが無限ループに入っている。無限ループに入っているということはApache内の処理(実際はPHP)が終わらなく、全てのプロセスが無限ループに入り、処理を受け付けなくなる。ということで、最初に申し上げた通り可用性が損なわれるので脆弱性と言えます。
(阿部)
なるほど、お客様から指摘をされた点に関しては、脆弱性とは言えないが保険的に修正を加えた方が良い。プログラムの無限ループにより、メモリエラーになる件に関しては脆弱性と呼べるということですね。
大変分かりやすい説明ありがとうございました。
最後に
脆弱性とは、セキュリティのCIAで、機密性(Confidentiality) 、完全性(Integrity)、可用性(Availability)が損なわれることを言います。機密性と、完全性に関しては一般的に知ってはいましたが、可用性に関しても重要ということが分かりました。(wikipedia更新しておこうかな)
今回、徳丸先生にライトな質問をしましたが、徳丸先生が取締役(CTO)として所属するEGセキュアソリューションズでは、脆弱性診断や、社内のセキュリティ勉強会の依頼などを行うことができます。モチヤでも脆弱性診断ではよくお世話になっております。
一見脆弱性とは判断付かないような事項も的確に指摘いただけますので、セキュアなシステムを開発するときは、ぜひ問い合わせてみてください。徳丸先生、お忙しいところお時間いただきありがとうございました。

阿部 正幸/ 代表取締役
Drupal歴15年、ウェブマーケティング、インフラ構築、AP開発が守備範囲です。
キャッチボール、筋トレ、日本酒、ウイスキーが好きです。天気の良い日に、誰かキャッチボールして、立呑に付き合ってください。
好きなDrupalモジュールはIMCEです。