この記事をシェアする

以前、このブログで「WordPressの管理画面に制限をかける(ver3.5.1)」という記事を書いたのですが、もうちょっと視野を広げて WordPress を設置・運用するに当たってセキュリティはどうしたら良いのか、ということを書きます。

大前提として、

  • 使用者のPCがウィルス対策ソフトなどを入れている。
  • Webサーバーの作りがしっかりしている。(ディレクトリの中身が見えるとか共用サーバーで他人のディレクトリにアクセス出来るとかSQLサーバーの作りがお粗末とかは問題外)
  • パーミッションちゃんとしましょうね(パーミッションはWebサーバーとそのユーザーによって推奨の設定が変わるのでこの記事では追求しません)

はあげておきます。

2017.2.7 update プラグインの事追記

1. Webサーバーとサイトの構成を見直す

最初から WordPress と関係無くなってしまいますが、そもそもPHPやデータベースを利用しない静的ファイルのみで構築されたWebサイトが一番堅牢です。
静的ファイルのみで良ければPHPとデータベースなんて使わないので、ウェブサイト経由で攻撃される手段がぐっと減ります(もっとも Apache や Nginx などWebサーバーそのもののメンテナンスは必要です)。

でも、これではCMSを使うメリットが無くなってしまいますよね。
そこで、CMSは社内LANの内側やもっとミニマムなら自分のPC内のローカルサーバーなど外部からアクセス出来ないところに設置し、記事更新時に静的ファイルを生成しWebサーバーにアップロードする方法があります。
ただし、サイト内検索やコメント機能などは Google 検索など外部サービスを利用する必要があります。

この方法の場合、WordPress なら StaticPress や Shifter を使えば可能ですし、元々静的ファイルを生成する MovableType もこの方法を取りやすいでしょう。

2. Webサーバー内部へのアクセスを見直す

進入経路は何も CMS の脆弱性をついたものとは限りません。Webサーバーにファイルをアップロードする時の通信を傍受されている可能性だってあります。

一番安全なのはWebサーバー内部へのアクセスを特定のユーザーのみに制限する事です。
例えば、IPアドレスで制限してしまう方法があります。

また、サーバーへのアクセスは SSH を基本にしましょう。
コマンドラインが苦手で FTPクライアントソフトを使う場合でも、SFTP または FTPS で接続するようにしましょう。
今時のレンタルサーバーで SFTP または FTPS を提供していないところはないと思いますが、 提供していなかったらサーバー選定の時点で外しておく ことも視野に入れましょう。

※なお AMIMOTO AMI(網元) はデフォルトで80番ポート(http)と22番ポート(SSH)のみ許可しています。FTPクライアントソフトを使うときはSFTPでアクセス可能です。(ステマ)

3. 最新版に保つ

すごく当たり前の事ですが、WordPress(CMS)に限らず、Webサーバーのミドルウェア(PHPなど)もセキュリティアップデートが提供されたら適用するようにしましょう。特にCMSは最新版を保つようにしましょう。
もちろん、本番環境でいきなりアップデートするよりも検証用の環境を用意した方が良いでしょう。

一例として執筆時点での WordPress の最新版は 3.9.1 です。このバージョンは 3.9 リリースからわずか3週間で提供されましたが、34個のバグが修正されています。アップデートしないということはその間に修正されたバグや脆弱性対策をも放置するということです。

「最新版に保つ」にも関わるのですが、「コアハック」と呼ばれる CMS本体のプログラムを改変することもやめましょう
当然ながら最新版にアップデートしたときに自分が改変した部分が無効になります。
また、あなたがセキュリティやプログラムの専門家でも無い限り、改変したせいで脆弱性が上がることもあり得ます。

WordPress の場合はテーマ、プラグインでコアプログラムの処理に手を加える事が出来る「フック」が用意されていますので、それを活用しましょう。
その上で、コアプログラムのバグで修正すべき点があれば、WordPress の Trac にパッチを送りましょう。

(追記)
たまに「WordPressをアプデートしたらプラグインが動かなくなるからやらない」という論調を見ますが、本末転倒です。
公式ディレクトリ掲載のプラグイン作者に対しては少なくても次のバージョンのβ版がリリースされた時点で「掲載しているプラグインが動作するかテストしてください」とアナウンスを出しています。
https://ja.wordpress.org/plugins/akismet/
参考までに「Requires」はどのバージョン以降なら動くのか。「Compatible up to 」はそのバージョンまでの互換性(動作確認)があるかどうか。です。
もちろん、公式ディレクトリ以外のプラグインのインストールはおすすめできないし、公式ディレクトリに掲載されていても長い期間更新の行われていないプラグインは代替プラグインを探したほうが良いでしょう。

4. CMSの管理画面へのアクセスを見直す

ようやくCMSの話です。
どんなCMSであっても 管理画面へアクセス出来る人はできる限り制限 しましょう。

「WordPressの管理画面に制限をかける(ver3.5.1)」で書いたことと重複するのですが、 管理画面に IPアドレスによる制限や Basic 認証 を施せば WordPress を起動する「前」に許可されていないアクセスを遮断することが出来ます。
もちろん WordPress のプラグインを使って2重認証をかけたりログイン失敗時に一定時間アクセスを不可能にすることも出来ます。

また 必ずパスワード自体を長く複雑なもの にしましょう。
「パスワードを覚えられない」ということであれば、LastPass などの外部サービスを使うのも手です。
なお、パスワードの管理自体は自己責任になります。笑い話ですが「パスワードを書いた付箋をモニターに貼る」なんて事の無いように。

また、WordPress であれば管理画面へのアクセスをSSLにすることも出来ます。

5. 万が一管理画面に入られても致命的な作業をさせない

万が一管理画面に入られてしまっても、悪意のあるコードを設置されたり、ファイルを書き換えたりといった操作させないために管理画面内で出来ることに制限をかけましょう。

以下、WordPressの場合ですが、

  • テーマ・プラグインの新規インストールと編集をさせない
  • 投稿画面や WidgetでPHPコードを入力実行させるようなプラグインは絶対入れない

最低限この2点は守りましょう。

最初のテーマ・プラグインの新規インストールと編集を行えないようにするには、wp-config.php に定数を書くことで可能です。

テーマ、プラグインの新規追加と更新、編集をさせないためには、wp-config.php に define('DISALLOW_FILE_MODS',true); と書きます。
ただしダッシュボードからのテーマとプラグインの更新(アップデート)も行えなくなりますので、SSH や SFTP・FTPS でファイルを更新する様にしましょう。

テーマ、プラグイン編集のみを制限するのであれば、wp-config.php に define('DISALLOW_FILE_EDIT',true); と書きます。

投稿画面や WidgetでPHPコードを入力実行させるようなプラグインについては以前記事を書きましたのでそちらもご覧ください。

まとめ

長々と書きましたが、

  • 静的サイト最強
  • Webサーバー内部へのアクセスを制限する
  • セキュリティアップデートは必ず!
  • CMSの管理画面に入られないようにする
  • 突破されても余計なことをさせない

これを守っていれば、そうそう改ざんされることはないと思います。


おまけ よくある「WordPressのセキュリティ対策」のホント?

WordPressのバージョン表示を隠しましょう

<meta name="generator" content="WordPress 3.9.1" /> を削除して〜、という記事がありますが、これの根拠はなんでしょうか?
たいてい「攻撃者は脆弱性のあるWordPressのバージョンを見つけて攻撃する」と紹介されていますが、本当に??

たとえ、<meta name="generator" content="WordPress 3.9.1" /> を削除しても

  • readme.html を見ればバージョン番号が書いてある。 readme.html は削除してもアップデートするとまたコピーされる(そのたびにやりますか?)
  • wp_enqueue_style、wp_enqueue_scriptできちんとバージョンの引数与えないと WordPress のバージョン番号がデフォルトで付与される(自作ならともかく、使っている全てのテーマやプラグインをチェックしますか?)

といった方法で容易にバージョンを推測することが可能です。
「やるな」とは言いませんが、readme.html の削除など、アップデートのたびに同じ作業をしなければならないのであれば、もっと別な部分に注力した方が良いと思います。

テーブルプレフィックスを変更しよう

元々テーブルプレフィックスのオプションはデータベースの設置数に制限を受けるような環境下で複数の WordPress を設置するために用意されたオプションです。
希にSQLインジェクションで攻撃するときにテーブルプレフィックスを決め打ちにすることはありますが、WordPress の場合ほとんど起こりえませんし、 サーバーに侵入させない、管理画面に侵入させない、ダッシュボードからPHPを入力・実行させないといった防御策 をとっていれば心配することもないように思います。
また WordPress の場合、SQLインジェクションや XSS などを含む脆弱性への対応は最優先で行われており、発見から短い期間でセキュリティアップデートが提供されています。

ユーザーID1とユーザー名adminが危険! authorアーカイブでユーザー名が見えるのも危険!

何をもって危険と言っているのでしょうか?
ユーザー名が分かったところで パスワードが破られなければダッシュボードにログインすることは出来ません
WordPress に限りませんが、他のウェブサービスとパスワードを同じものにしたり、桁数が少ない、容易に推測できるパスワードであればユーザー名が何であれ危険な事には変わりません。
「WordPressの管理画面に制限をかける(ver3.5.1)」でも書きましたが、複雑で長いパスワードにしたり、ログイン画面へのアクセスそのものを制限したり、この記事で書いたログインされてしまっても致命的な作業をさせない事の方が大事です。


万が一改ざんされてしまったら

改ざんされてしまったらすぐに復旧しなければなりません。
とはいえ書き換えられた場所を探したり修正するのは一苦労ですし、漏れがあれば再度改ざんされる危険もあります。
(彼らの手口は巧妙です)

万が一に備え、 Webサーバーのデータとデータベースのバックアップは定期的に取りましょう。
バックアップさえあればその時点のデータからになりますが、短時間での復旧が可能になります。

WordPress であればデータベースを含め丸ごとバックアップを取ってくれるサービスやプラグインがたくさんあります。
また、レンタルサーバーであればバックアップのオプションを提供しているところもあります。有料の場合が多いですが、万が一の保険と思って積極的に使いましょう。

AWSであればサーバー自体を丸ごとバックアップしていくことも可能です(スナップショット)。
定期的にスナップショットを取り、S3へ転送するようなプログラムを自作することも可能ですので、興味のある方は調べてみてください。


ちょっとかっとなって書いた部分はあるのですが、今回書いた記事は前から口頭でお話ししていた部分も含みます。
また、下記の記事も合わせてお読みください。

追記

改ざんやダウンタイムの検知について最も手軽に始められる方法を書きましたので、あわせてご覧ください。
この記事でWordPressをはじめとするバージョン番号に関する言及もあります。

この記事をシェアする