これによると、PHPをはじめとする多くのWebアプリケーション開発プラットフォームに対して、CPU資源を枯渇させるサービス妨害攻撃(DoS攻撃)が可能な手法が見つかったということです。この攻撃は、hashdos と呼ばれています。
概要
PHPなど多くの言語では、文字列をキーとする配列(連想配列、ハッシュ)が用意されており、HTTPリクエストのパラメータも連想配列の形で提供されます。PHPの場合、$_GET、$_POSTなどです。連想配列の実装には、高速な検索が要求されるためハッシュテーブルが用いられます。ハッシュテーブルは、文字列を整数値(ハッシュ値)に変換するハッシュ関数を用いて、平均的には一定時間に検索・挿入・削除が行えるデータ構造です。しかし、ハッシュ値が一致する(衝突する)キー文字列については、通常ハッシュテーブルは順次的な探索となり、検索・挿入などが遅くなります。
hashdosは、ハッシュ値が同じになるキーを多数POSTパラメータに含ませることにより、CPU資源を枯渇させる攻撃です。cryptanalysisによると、300k、500k、8MBのデータを用いた処理時間は以下の通りだそうです。
- 8 MB of POST data - 288 minutes of CPU time
- 500k of POST data - 1 minute of CPU time
- 300k of POST data - 30 sec of CPU time
影響を受けるプラットフォーム
Perl以外の多くの言語で影響があります。Java(Apache Tomcat7.0.22以下、同6.0.34以下、同5.5.34以下) 、PHP、ASP.NET、Python、Ruby(1.8.7-p356以下のみ)などです。詳しくは、cryptanalysisの解説を参照して下さい。影響
DoS攻撃の最中はCPU資源が攻撃に割り振られてしまい、サービスの提供が困難になると考えられます。Apache Killerと異なり、メモリ資源が枯渇するわけではないので、攻撃がやめば直ちにサービスは回復するようです。
解決策、回避策
パッチが提供されている言語については、パッチを速やかに適用して下さい。ASP.NETについては、MS11-100のセキュリティパッチにて修正されています。
Apache Tomcatについては、7.0および6.0については対策バージョンが出ているので、速やかにバージョンアップしてください(2012/1/6追記)。Tomcat5.5についても対策バージョン(5.5.35)が出ました(2012/1/19追記)。
PHPについては、PHP5.3.9にて修正される予定です。PHP5.3.9RC5-devおよびPHP5.4.0RC4にて修正済みであることを確認しました。PHPの修正は、受け付けるパラメータ数の上限を規定するもので、php.iniのmax_input_varsとして指定できます。デフォルト値は1000ですが、必要最小限の値を指定することで安全性が高まります。PHPの修正は、パラメータ数を制限するものですので、根本的解決とは言えませんが、現実的には、パラメータが1000以上必要というアプリケーションはまずないと思われるので、現実的な対応としてはありだと思います。
PHP5.3.9が出るまでの間は、回避策として、php.iniで以下を制限するとよいでしょう。
- post_max_size(POSTパラメータの最大バイト数; デフォルトは8MB)
- max_input_time(入力処理の最大時間; デフォルトは-1(無制限))
一方、max_input_timeを短く設定すると、たとえ攻撃にあっても、攻撃の影響を緩和できます。max_input_timeは、「サーバがすべてのデータを受け取ってからスクリプトの実行を開始するまでの時間」ということで、hashdosの実行時間(POSTデータを$_POSTにセットする時間)と関連します。
これらの回避策は、根本的対策ではありません。とくに上記パラメータを絞り込みできないアプリケーションでは、できるだけ早期にPHP5.3.9への移行を推奨します。
あるいは、WAFによりパラメータ数を制限できれば、有望な対策となります。
追記(2011/12/30 23:20)
mod_securityによる対策が有効であることを確認しました。mod_securityの最新版(2.6.3)およびCRS(Core Rule Set)の最新版(2.2.3)にて確認しました。mod_securityのルールとしては、以下の2つが効いています。
- SecRequestBodyNoFilesLimit
- modsecurity_crs_23_request_limits.conf の Maximum number of arguments in request limited
前者は、ファイル以外のPOSTのボディサイズ制限で、デフォルトは1MBです。
後者は、パラメータの個数を制限するルールで、デフォルトは255です。
いずれも、「SecRequestBodyAccess On」を設定しておかないと有効にならないと思います。これは、POSTパラメータをmod_securityでチェックするという指定です。
【参考】mod_securityの導入方法をブログに書きました
また、Ruby1.9は対象でなく、Ruby 1.8.7-p356以下が対象となります。Ruby 1.8.7-p357以降、1.9.xでは対応済みです。
追記(2011/12/31 12:30)
28C3の講演資料によると、PHPのsuhosinパッチが回避策として挙げられています。未検証だったので紹介していませんでしたが、こちらも検証してみました。Ubuntuの場合、パッケージでPHP5を導入している場合は、suhosinパッチを簡単に導入できます。
$sudo apt-get install php5-suhosin/etc/php5/apache2/conf.d/suhosin.ini というファイルが作られますので、このファイルによりsuhosinの設定が可能です。
hashdosに効果があるのは以下のパラメータです。
;suhosin.post.max_vars = 1000それぞれ、POSTパラメータ数とリクエストのパラメータ総数を制限するものです。制限する場合、エラーにするのではなく、超過分を無視するようです。
;suhosin.request.max_vars = 1000
どちらもデフォルトは1000となっています。この程度の値でも、hashdosには相当の効果が見込めます。suhosinの場合、先のPoCで6分弱掛かった際のパラメータ数は65536でした。これが1/65になるわけですが、hashdosの実行時間はパラメータ数に2乗に比例しますので、
6 * 60 / 65 / 65 = 0.085と、0.1秒未満になる計算です。通常はパラメータ数が1000近くなることはないと思いますので、さらに絞り込むと安全性が高まります。その場合、行頭のコメント記号「;」を削除することをお忘れなく。
mod_securityの新規導入は大変ですし、PHP5.3.9もまだリリースされてないようですので、PHPアプリケーションをhashdosから防御するには、当面suhosinが有効だと思います。ただし、suhosinの導入による副作用も考えられますので、まずはテスト環境でテストしてから本番環境に適用することをお勧めします。
また、Apacheの設定で簡易的な対策をとることも可能です。以下はPOSTのボディサイズを100K以下に制限する指定です。Apacheのマニュアルに紹介されている例です。
LimitRequestBody 102400この方法は、Apacheを使っている環境では、言語を問わず有効です。
但し、大容量ファイルのアップロード機能があるようなアプリケーションでは、この対策は難しいでしょう。
まとめ
hashdosについて報告しました。hashdosの特徴は簡単(POSTリクエスト一発)でCPUを枯渇させることができるという意味で、カジュアルなDoS攻撃ができることが特徴です。一方、メモリ資源は枯渇しないことから、ApacheKillerほどの破壊的な攻撃ではないという印象を受けました。年末・年始にかけて迅速な対応ができない職場も多いと思いますが、できるだけ早期に回避策を導入すること、Webサイトの監視を強化すること、hashdosによる攻撃の情報に注意することを推奨します。
[PR]
「安全なWebアプリケーションの作り方」DRMフリーのPDFによる電子版もあります。