wordpressのセキュリティ対策

wordpressは基本的にphpというプログラムで構成されています。そのため、セキュリティをすり抜けてphp特有の攻撃を受けてしまうこともあります。バージョンによって無効のものもありますが、例えば、変数汚染、eval、Nullバイト、ディレクトリトラバーサル、インクルードの脆弱性をつく、セッションハイジャック、パスディスクロージャ、ファイルアップロード攻撃、コマンドインジェクション、不正リクエスト、ヘッダインジェクションなど。更にXSSやスクリプトインジェクション、クロスサイトリクエストフォージェリ、SQLインジェクションといったものもあります。

また、wordpressは世界的に広く利用されているCMSであるため、あらゆる攻撃の標的になりやすい性質があります。そのため、不正にログインを試みる総当たり攻撃であるブルートフォースやリバースブルートフォース、そしてパスワードスプレー攻撃などの対象になりやすい傾向にあります。Apacheのログにはそういった攻撃の痕跡がたくさん残っていたりします。IPアドレスを変えながらアタックしてくるケースも多いです。

wordpressの最も簡単なセキュリティ対策は?

wordpressのセキュリティ対策に力を入れているサーバを借りることです。これは共有サーバでも同じです。例えば国外からの接続に対してwordpressの管理画面やXML-RPC API 、REST APIなどにアクセス制限をかけたり、wordpressのログインに何回か失敗すると、一定時間同じアクセス元から接続できないようにしている、といった具合です。また、Webアプリケーションファイアウォール(通称WAF)を提供しているレンタルサーバだと、より堅固な防御となります。

自宅サーバにwordpressをインストールしている場合は、残念ながら上記のアタックに対し、自力でセキュリティ対策するしかありません。エスケープしたり、なるべくフォームを使わないようにしたり、htaccessでアクセス制限もしくはBasic認証をかけたりします。

wordpressの具体的なセキュリティ対策

変数汚染

古いバージョンのphpで「register_globals = On」となっている場合に発生。php4.2.0以降ではデフォルトでOffになっています。php.ini(以下、設定ファイルと表記します。)で「register_globals」を無効にしてforeachやextractなどで変数展開せず、$_GET[変数名]という形式で記述することによって防御できます。

eval

wordpressでは、投稿記事内にもeval関数を用いてプログラムを記述することができます。しかし、出力時にきちんとエスケープされていなければセキュリティ的に穴が開くため、wordpressの標準だと記述できないようになっています。この関数は便利なのですが、基本的にはwordpressで利用しないほうが無難です。セキュリティを考量すると、evalは使用せず、wordpressのショートコードを使います。というか、wordpressテーマのテンプレートやプラグインをいじれば、セキュリティ面でリスクのあるevalはそもそも必要ありません。少し遠回りになるだけです。

Nullバイト

リクエストを$_POSTや$_GETなどで受け取ることで発生。セキュリティ措置としては最初の処理で$_GET、$_POST、$_REQUEST、$_COOKIEからNullバイトを除去。その際、バイナリセーフな関数でチェック。php5.3.5以降では処理が失敗するため不要。新しいバージョンへの移行でwordpressは守られます。

ディレクトリトラバーサル

phpファイルに記述した$_POSTや$_GETなどの変数で受け取ることによって発生。セキュリティ処理としては「ini_set('open_basedir', '/制限したいパス/');」で対応する。制限したいパスはApacheだと「/var/www/html/」になります。phpのバージョンは、5.2.6と5.3.4以降にします。新しいバージョンへの移行でwordpressは守られます。

インクルードの脆弱性

リクエストから受け取った値をinclude、include_once、require、require_onceの引数に入れることで脆弱性が発生。設定ファイルで「allow_url_include = 0」と指定すればwordpressは守られます。アタックは成立しません。

セッションハイジャック

不正に取得したセッションIDを使って正規ユーザのセッションを乗っ取るアタックのことです。設定ファイルで「session.use_cookies = 1」「session.use_only_cookies = 1」「session.use_trans_sid = 0」とし、cookieのみでセッションIDを管理することによってwordpressは防御。

パスディスクロージャ

phpスクリプトのフルパスがエラーレポートによって出力されてしまう性質を利用したアタックをいいます。wordpressサイトでたまに英数字の文字が横に並んでいるブログを見かけますよね。あれは、wordpressのアップデートなどによって関数などが使えなくなった時に出てきます。通常、テスト動作確認のためにエラーレポートを出力させますが、設定ファイルでの変更を忘れるとエラーがあれば出てきます。これは、本番環境で「display_startup_errors = 0」「display_errors = 0 」へ変更することによって回避できます。

ファイルアップロード攻撃

悪意あるコードを挿入した不正ファイルをアップロードし、そのファイルにアクセスすることにより成立してしまいます。セキュリティ処理としてはmove_uploaded_file()関数で「$_FILES['FileUpload']['name']」をハッシュ化。ハッシュ化が終わった時点で元のfile名とハッシュ化されて保存されたfile名をデータベースに登録。取り出すときには元のファイルのMIMEタイプなどから照合します。

コマンドインジェクション

ウェブサーバーのOSで使われるコマンドを注入することにより発生。セキュリティ措置としてはescapeshellarg()を用います。この関数はシェル引数として使用される文字列をエスケープします。また、if文の最初で、nullバイトを取り除き、誤作動を発生させないようにします。

ヘッダインジェクション

input要素のname属性にメールの宛先を指定して外部からのリクエストを受け取っているフォームやメールのヘッダ部分に改行コードを含む文字列を注入できる環境などで発生。mb_send_mail()関数の第四引数に改行コードを挿入されることで起こるため、メールヘッダに改行が入っていればメール送信ができないようにプログラムを作ることで回避できます。

スクリプトインジェクション

JavaScriptやVBScriptなどを他人のホームページの内容に挿入することで、ホームページを訪問したユーザに対し、直接的に悪意あるスクリプトを実行させるというアタック方法です。出力時にエスケープすることで、悪意あるコードを無効化し、wordpressを保護。

XSS(クロスサイトスクリプティング)

間接的に悪意あるスクリプトを実行させることで発生。こちらも出力時にエスケープすることによってwordpressを守ります。

クロスサイトリクエストフォージェリ

ログインしていることを前提としており、正規ログインユーザと同等の権限を持って、正規ユーザの意図しない操作が行われます。セキュリティ措置としては、プログラム処理において最初に作成したセッション変数とフォームから渡ってきた変数トークンが一致するかどうかを確認。一致しなかった場合にはアタックされたことになります。いわゆるワンタイムトークンのことです。

SQLインジェクション

SQL文に意図しない命令を挿入することで成立。セキュリティ対応は、SQL文(命令文)をエスケープします。MySQLではmysql_real_escape_string()を使いますが、この関数はphp7以降で削除されました。現在ではプログラム側のエスケープが不要になるプリペアドステートメントをできる限り利用されることが推奨されています。phpではPDOという専用クラスを使います。

ブルートフォース

アカウントに対してパスワードをランダムに送信するタイプ。一定回数のログインの失敗によって、一定時間そのアカウントをロックしたり、本人確認を要求したりして対応。これによってwordpressは防御。

リバースブルートフォース

一つのパスワードに対して、アカウントをランダムに送信するタイプ。上記と同様に対応することでwordpressは防御。

パスワードスプレー

複数アカウントを対象に、一つのパスワードを送信して繰り返すタイプ。上記と同様に対応することでwordpressは防御。

その他のwordpressへのセキュリティ

テーマやプラグインは、wordpress本体の公式からインストールします。公式でないものは審査もないため、悪意あるコードが注入されてしまう確率が高くなり、セキュリティ的によろしくないです。もちろん、wordpress公式でないからといって全てに悪意がある訳ではありません。趣味で作っている人や貢献しようとして作っている人もいることと思います。しかし技術的には容易であることを認識しておく必要性があります。

また、wordpressと対になるデータベースのバックアップもとっておきましょう。「WP-DBManager」というプラグインを使えば、一定期間ごとにサーバへ保存したり、メールでバックアップファイルを送信したりできます。「phpMyAdmin」というウェブアプリケーションを利用すれば、直接ダウンロードできます。

バックアップさえとって置けば、改ざんされる前の状態へ簡単に戻せます。いつ改ざんされたかによってかかる手間も異なりますが、それでも全てが消えてしまうよりマシです。記事を投稿する頻度によってバックアップ期間を定めると良いでしょう。wordpress本体は、一旦削除して新たにインストールすればいいだけです。クリーンな状態にすぐもどります。wordpressを一旦削除するのは、wordpress本体に悪意あるコードが注入されている可能性があるからです。

まとめ

これらのセキュリティ対策を個人で行うには、限界があります。wordpress初心者なら、上記のセキュリティに関する単語が何を意味しているのかさっぱり分からないかもしれません。wordpress運営側もセキュリティ対策を講じて頻繁にアップデートを繰り返していますが、何分有名すぎるCMSであるため、いたちごっこというのが現状です。そのため、最も簡単な防御法は、wordpressのセキュリティに力を入れているサーバを選ぶことです。