2015年12月7日月曜日

WordPressの侵入対策は脆弱性管理とパスワード管理を中心に考えよう

この記事はWordPress Advent Calendar 2015の7日目の記事です。

今年初めてWordCamp Tokyoにて講演の機会をいただき、WordPressのセキュリティについて話しました(スライド)。そこでもお話ししましたが、WordPressに限らず、Webサイトへの侵入経路は2種類しかありません。それは以下の2つです。
  • ソフトウェアの脆弱性を悪用される
  • 認証を突破される
したがって、侵入対策としては以下が重要になります。
  • 全てのソフトウェア(OS、Apache等、PHP、WordPress本体、プラグイン、テーマ等)を最新の状態に保つ
  • パスワードを強固なものにする
以上! と叫びたい気分ですが、それではシンプル過ぎると思いますので、以下、WordCampでお話した内容とリンクしながら、もう少し細く説明したいと思います。

全てのソフトウェアを最新の状態に保つ

WordPressサイトを前提とすると、以下のソフトウェアの脆弱性を悪用した攻撃の可能性があります。
  • Apache、OpenSSL等
  • PHP
  • WordPress本体
  • WordPressのプラグイン、テーマ
これらのうち、Apache、OpenSSL、PHP等については、できればソフトウェアのアップデートを自前でやるのではなく、ホスティング業者等が代行してくれるサービスを選ぶとよいでしょう。昔からあるレンタルサーバー(共用ホスティング)も該当しますし、PaaS(Platform as a Service)も原則としてアップデートを事業者側でやってくれるはずです(要個別確認)。

WordPress本体とプラグイン、テーマのアップデートは重要です。とくに、プラグインとテーマについては、セキュリティ上の品質が本当にまちまちなのが困ったところです。WordCampでデモに用いたのはMailPoetというプラグインですが、過去のバージョンではテーマアップロードの際に認証をチェックしておらず、誰でも自由に勝手なテーマをアップロードできたという脆弱性があり、このため、脆弱性のデモも以下のように単なるアップロードフォームで攻撃できてしまいました(攻撃がマネできないように一部伏せ字)。
<body>
<form action="http://examle.jp/wp-admin/admin-post.php?page=xxxxxxxxxxxx&action=xxxxx" method="post" enctype="multipart/form-data">
<input type="text" name="action" value="xxxxxxxxx">
<input type="text" name="submitter" value="xxxxxxx">
<input type="text" name="xxxxxxxxxxxxx" value="xx">
<input type="file" name="xxxxxxxxx">
<input type="submit" value="攻撃">
</form>
</body>
このため、プラグインとテーマのアップデートは特に重要です。具体的には、
  • 本当に必要最小限のプラグインとテーマのみを導入する
  • プラグインとテーマのアップデートは自動化する
ことが重要です。
自動アップデートするとサイトが動かなくなることが心配という人もいるでしょうね。そういう心配には、クラウドのイメージバックアップ機能によりサイト全体を保存しておき、万一サイトが動かなくなった場合はバックアップから戻した上でゆっくりと原因分析をするとよいでしょう。ただし、バックアップから戻した直後はプラグイン等が古いわけですから、そのままの状態で公開してはいけません。動かなくなった原因を究明して対処を行い、プラグインのアップデートをすませてから公開するべきです。

パスワードを強固なものにする

もう一つの侵入経路は、認証を突破されるケースですが、WordPressの場合は「パスワードがばれちゃった」というケースが該当します。具体的な手口としては以下の様なものがあります。
  • パスワードが辞書に載っているもので、パスワードの辞書攻撃により侵入された
  • パスワードを他サイトでも使い回ししていて、パスワードリスト攻撃により侵入された
  • 管理端末がウイルス感染して、ウイルスがパスワードを漏洩させた
したがって、対策としては、下記が有効です。
  • よいパスワードを設定する(他で使っていない、辞書に載っていない、できればランダムな)
  • 管理用パソコンのウイルス対策(ソフトウェアのアップデートとウイルス対策ソフト)
WordPressの場合、よく「管理者のユーザ名としてadminは避けましょう」ということが言われます。確かに、admin決め打ちの攻撃も多いのでできればadminを避けたほうがよいとは思いますが、WordPerssは、ログイン名が外部にバレやすいという特性があります。下記は、WPscanというツールを用いてWordPressの辞書攻撃を行った結果の例ですが、adminユーザの方は良質なパスワードを設定していたので破られなかったものの、yamadaユーザはtiggerというパスワードが辞書攻撃によりばれてしまいました。
  +----+--------+------+----------+
  | Id | Login  | Name | Password |
  +----+--------+------+----------+
  | 1  | admin  |      |          |
  | 4  | yamada |      | tigger   |
  +----+--------+------+----------+
つまり、良質なパスワードをつけることが第一優先であり、その他は副次的な対策である、ということです。
WordPressの場合、ログインユーザ名を隠すことは不可能ではないようですが、かなりハードルが高いといえます。このため、ログインユーザ名がわかってしまうことは許容し、パスワード管理に注力することが得策であると考えます。

ファイルのパーミッション

レンタルサーバーにおいては、ファイルのパーミッション設定が重要となります。これは、一つのApacheを複数ユーザーで共有するという特性上必要なものです。
レンタルサーバー事業者側の対策が十分であれば通常は問題になることはないはずですが、現実に大規模な攻撃に至ったケースもあるので、利用者側でもできる対策はしておきましょう。
レンタルサーバーにおいては、以下のパーミッション設定が基本となります。
  • HTMLやJS、CSS、画像は604
  • PHP スクリプトは 600
  • CGI スクリプトは 700
  • ディレクトリは 701
※レンタルサーバー事業者によっては多少異なるパーミッションを指定している場合があります

静的なファイルに関しては、レンタルサーバ独自の特性として、1桁目(右端の桁)にReadパーミッションが必要となります。その他、PHPスクリプトやCGIスクリプトについては、ファイルオーナーのみに権限を与えることが重要です。

その他の「対策」について

上記二点がWordPressサイトのセキュリティ施策としてもっとも重要なものですが、「WordPress セキュリティ」等のキーワードで検索すると、「WordPressを守るために必須の10個の対策」みたいな記事をよく見かけます。
これらの記事を読むと、往々にして「それ、無意味とは言わないけど、それほど効果は期待できないから…」というものが多いです。
以下、それらの代表例を紹介します。

テーブル名のプレフィックをデフォルトから変更することの効果

WordPressのテーブル名にはデフォルトでwp_というプレフィックスがつきますが、そのままだとSQLインジェクション攻撃を受けるので、必ず他のものに変えるようにという記事をよく見かけます。
やらないよりはやった方がよいと思いますが、SQLインジェクション脆弱性があるという前提では、実はそれほど効果はありません。
なぜなら、SQLデータベースにはinformation_schemaという機能があり、テーブル名やデータベース名(スキーマ)は、ここから分かるからです。具体的には、information_schemaに対してSQLインジェクション攻撃をかけることで、テーブル名等の情報を得ることができます。
したがって、プレフィックスを変更すると、へっぽこな攻撃者や攻撃ツールは避けることができるかもしれませんが、腕の良い攻撃者からの攻撃は避けられません。
つまり、SQLインジェクション脆弱性があり、それを攻撃者に見つけられた時点で終わりなのです。このため、SQLインジェクション脆弱性を全力で避ける必要があります。
WordPressのプラグイン等であれば、WordPressの提供するプレースホルダ機能でSQLを呼び出すこと、素のPHPスクリプトであれば、PDOのプレースホルダ機能を用いてSQLを呼び出すことで、SQLインジェクション対策を行って下さい。

.htaccess等で wp-config.php をアクセス制限することの効果

.htaccess等を用いて、外部からwp-config.phpのアクセス制限をするという施策はよく見かけますが、この「対策」が役に立つケースは、実はそれほど多くありません。
wp-config.phpは設定のためのパラメータ設定のPHPスクリプトが並んでおり、このファイルにアクセスしても何も起きません。外部に公開されているPHPスクリプトなのでそれは当然です。問題は、wp-config.phpに記述されたデータベースのユーザ名やパスワードが漏洩することです。
しかし、wp-config.php自体にアクセスしてもそのソースコードは表示されません。表示されるとしたら、なんらかの脆弱性がある場合ですが、wp-config.php自体は単純なものなので、これ自体に脆弱性がある可能性はまずありません。したがって可能性としては、下記が考えられます。

(a) PHPのインストールを忘れていてwp-config.phpが生のままダウンロードされる
(b) 他のPHPスクリプトにディレクトリトラバーサル等の脆弱性がありwp-config.phpを閲覧される
(c) PHP等に脆弱性があり、PHPのソースが漏洩する

(a)は論外のケースであり、インストールの手順をしっかり立てましょう。万一 wp-config.phpの内容を閲覧されてしまった可能性がある場合、すみやかにデータベースのパスワードを変更する必要があります。また、念のため、データベースをすべて削除しておくとよいでしょう。(まだデータは入っていないはずなので)

(b)はあり得るケースですが、残念ながらこの場合は .htaccessの設定では防げません。.htaccessで制限しても、PHP等からは読めるからです。そうでないと、PHPスクリプトからインクルードもできないことになりますよね。

(c)も過去にはありました。CGI版のPHPにCVE-2012-1823という脆弱性があり(参考)、以下のURLのように、?-s をURLにつけることでwp-config.phpのソースを閲覧することができました。
  • http://example.jp/wp-config.php?-s
なんだ、効果があるじゃないかと思われるかもしれませんが、CVE-2012-1823に関しては、リモートコード実行もできたので、.htaccess による制限だけでは、結局ソースコードの閲覧も含め、さまざまな攻撃を許してしまう状況でした。
実際、レンタルサーバー事業者の中には、上記 ?-s による攻撃のみを重視した結果、肝心のリモートコード実行を防ぐことができず、重大な攻撃を受けてしまったところもあります。
将来見つかる脆弱性において、PHPのソースを閲覧できるものが出てくるかもしれませんので、その場合は .htaccess による制限も効果はあることになります。よって、「やっても無駄」というつもりはありませんが、今後そのような脆弱性が発見される見込みはそれほど高くないと思いますので、優先順序としては、脆弱性やパスワードの管理をしっかりやった後、ということです。

SiteGuard WP Pluginのすすめ

今までの話がWordPressのセキュリティ対策の「原則」の話ですが、いくら注意していても設定漏れ等により侵入を許す場合もあり、また長いパスワードをつけているので辞書攻撃の被害を受けないことはわかっていても、延々と攻撃を受け続けると気分はよくありません。
このため、付加的なセキュリティ対策についての検討をするところですが、私からはSiteGuard WP Pluginを紹介したいと思います。
SiteGuard WP Pluginは、WordPressのログイン周りに特化した無料のプラグインで、以下の機能を提供します。


管理ページアクセス制限ログインしていない接続元から管理ディレクトリ(/wp-admin/)を守ります。
ログインページ変更ログインページ名を変更します。
画像認証ログインページ、コメント投稿に画像認証を追加します。
ログイン詳細エラー
メッセージの無効化
ログインエラー時の詳細なエラーメッセージに変えて、単一のメッセージを返します。
ログインロックログイン失敗を繰り返す接続元を一定期間ロックします。
ログインアラートログインがあったことを、メールで通知します。
フェールワンス正しい入力を行っても、ログインを一回失敗します。
ピンバック無効化ピンバックの悪用を防ぎます。
更新通知WordPress、プラグイン、テーマの更新を、メールで通知します。
WAFチューニングサポートWAF (SiteGuard Lite)の除外リストを作成します。
JP-Secure社の紹介記事より引用

SiteGuard WP Pluginのレビューについては既に多くの記事がありますので、そちらをお読みいただければと思いますが、私がよいと思うポイントは下記の三点です。
  • SiteGuard の不正ログイン防止に特化している
  • 簡単に導入できて効果が高い
  • プラグイン自体の脆弱性対策がなされている(重要)
「セキュリティプラグイン」と称していながらSQLインジェクション脆弱性があったなんてものも過去ありましたので、プラグイン自体がセキュアであることは現実問題として非常に重要です。

SiteGuard WP Pluginのインストールはこちらから。

まとめ

WordPressの侵入対策について説明しました。
WordPressに限りませんが、ウェブサイトに対する侵入対策としては、脆弱性管理とパスワード管理が極めて重要であり、これらをおろそかにして他の(楽な)対策をいくら積み重ねても、あまり効果はありません。レンタルサーバーを利用する場合は、ファイルのパーミッション設定も重要です。
本稿の内容が皆様のサイトの安全性寄与にお役に立てれば幸いです。


0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ