Help us understand the problem. What is going on with this article?

ModSecurityによるStruts脆弱性対策

More than 5 years have passed since last update.

日本のStruts1の脆弱性(CVE-2014-0114)対応は素早く粛々と行われているようで、なによりです。

http://qiita.com/kawasima/items/670d2591bc8fea19dc1d

こちらの記事で

  1. BeanUtilsのResolverを差し替える方法
  2. RequestProcessorを差し替える方法

について書きました。

どちらもJavaアプリケーションレイヤでの対策ですが、ModSecurityを使ってもキチンと穴塞げるようなのでやってみました。これはAPサーバの前にApacheがいることが前提になりますが、対策は非常に簡単です。

ModSecurityのセットアップ

Ubuntu系は、aptでインストールできます。

% sudo apt-get install libapache2-modsecurity

そうすると、/etc/modsecurity/modsecurity.conf-recommendedにコンフィグのexampleが置かれているはずなので、これをコピーして編集します。

% sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

ファイル最後尾にでも、

SecRule ARGS_NAMES "(^|\.)[cC]lass\." "deny,log,status:403"

を追加します。これはclass,Classを含むネストしたパラメータの場合、そのリクエストを拒否し、ログを書き、403でレスポンスを返すというルールです。詳しくはリファレンスマニュアルをみてください。
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual

/etc/apache2/mods-available\mod-security.conf中に、Include "/etc/modsecurity/*.conf"の記述があるので、後はモジュールを有効化して、再起動するだけです。

% sudo a2enmod mod-security
% sudo apache2ctl restart

テスト

それではこのルールが有効かどうか試してみます。あとでマルチパートのリクエストもテストするので、そういうときはJMeterを使うと便利です。

スレッドグループにHTTPリクエストのサンプラーを追加し、パスやパラメータを設定します。

SnapCrab_NoName_2014-5-3_0-16-59_No-00.png

これを"結果をツリーで表示"のリスナーを追加して実行すると、実行結果が見れます。

SnapCrab_NoName_2014-5-3_0-17-34_No-00.png

ちゃんと、403で弾かれてますね!

さて、問題はServletFilterでは難しかったMultipartのパラメータもチェックできるか、です。mod_securityはMultipartも一度パースして、再構成して後ろのフックに回す機能があります。JMeterでマルチパートのリクエストを作るのはチョー簡単です。以下のようにメソッドをPOSTにしてMultipartのチェックボックスにチェックつけるだけです。

SnapCrab_NoName_2014-5-3_0-22-48_No-00.png

さて、こちらも実行してみます。

SnapCrab_NoName_2014-5-3_0-25-54_No-00.png

ヤリました!マルチパートでもちゃんと403が返りルールにしたがってチェックかかっていることが分かります。

正しくModSecurityが動いた結果かどうかは、auditログが出力されているので、そちらで確認できます。

/var/log/apache2/modsec_audit.log
[03/May/2014:00:25:06 +0900] U2O40n8AAQEAADImF4IAAAAB 127.0.0.1 32834 127.0.0.1 80
--de079d50-B--
POST / HTTP/1.1
Connection: keep-alive
Content-Length: 238
Content-Type: multipart/form-data; boundary=ioU4y3E5yzasxHc7HgXGrFwUCF9AKmWVKAHv5Zh
Host: localhost
User-Agent: Apache-HttpClient/4.2.6 (java 1.5)

--de079d50-I--
class%2eclassLoader%2ehoge=hehehe
--de079d50-F--
HTTP/1.1 403 Forbidden
Vary: Accept-Encoding
Content-Length: 277
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1

--de079d50-E--
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /
on this server.</p>
<hr>
<address>Apache/2.2.22 (Ubuntu) Server at localhost Port 80</address>
</body></html>

--de079d50-H--
Message: Access denied with code 403 (phase 2). Pattern match "(^|\\.)[cC]lass\\." at ARGS_NAMES:class.classLoader.hoge. [file "/etc/modsecurity/modsecurity.conf"] [line "207"]
Action: Intercepted (phase 2)
Stopwatch: 1399044306059830 1099 (- - -)
Stopwatch2: 1399044306059830 1099; combined=91, p1=34, p2=44, p3=0, p4=0, p5=13, sr=0, sw=0, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.6.3 (http://www.modsecurity.org/).
Server: Apache/2.2.22 (Ubuntu)

--de079d50-J--
Total,0

--de079d50-Z--

こんな感じでログが出力されています。大丈夫そうですね。

ModSecurityによるオーバーヘッド

さて、既存の環境にModSecurityを適用する場合、気になるのはその性能オーバーヘッドです。
せっかくのJMeterなのでスループットを測ってみます。サーバサイドの処理はなく普通のApacheのエラーを返すだけの処理です。

添付ファイル(500kb)あり (100スレッド/無限ループ)

ModSecurity スループット(/sec) 90%ライン (msec)
有(正常リクエスト) 527 297
有(正常リクエスト) 504 335
1147 6

添付ファイルなし (100スレッド/無限ループ)

ModSecurity スループット(/sec) 90%ライン (msec)
有(正常リクエスト) 6415 8
有(攻撃リクエスト) 4444 37
7199 1

マルチパートをパースして再構成するので、やはりマルチパートでのリクエストが多い場合は、結構なオーバーヘッドになるようです。が、Apacheに余裕があってファイルアップロードのリクエストがそんなに殺到するものでない場合においては、90%ラインは実用的な数値なので、ModSecurityの導入検討の価値はあるかと思います。

kawasima
Clojure関連のことをブログがわりに書き綴ります。 ※ここでの発言はシステムエンジニアを代表するものであって、所属する組織は二の次です。
https://github.com/kawasima/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした