随時更新:WordPressサイトのセキュリティー向上のノウハウ

ウオトミズ(UOTOMIZU)の中の人

概要

当記事では、WordPressサイトに導入可能なセキュリティー対策をまとめた。必須の対策から、多くのサイトで対策されていないが導入しておいた方が良い対策までを網羅している。当記事は基本的に管理人自身の知識のログのために作成しているが、予算の少ない中小企業や個人管理人にもぜひ参考にしてもらいたい。安全なサイト運営のためセキュリティ向上に貢献できれば幸いだ。利用している端末がウイルス感染していると、対策が無意味になるのでご注意を。

必須: 常時SSL(https)化

常時SSL(https)化
いついかなる時も、https://で通信されるようにすること。http://でアクセスしても、https://にリダイレクトされなければならない。

常時SSL(https)化がされていないサイトをブラウザは安全でないとユーザーに知らせるようになったので、必須である。常時SSL化されてない方が珍しい気もする。知識があれば、導入自体は無料でできる。サーバー会社に手順がのっているので、実施できていない場合は直ちに実施してほしい。きちんと導入できているかについては、SLL Labshttps://www.ssllabs.com/ssltest/でチェックできる。

必須:不必要なファイルの削除と重要ファイルのアクセス拒否

  • license.txt
  • wp-config-sample.php
  • readme.html
  • wp-comments-post.php

これらのファイルは削除するかアクセスできないようにする。

wp-config.phpのファイルはアクセスできないようにする。

各ファイルにアクセスできないようにするには、.htaccessに以下を記載。

 

例)wp-config-sample.phpreadme.htmlを削除し、他のファイルはアクセス拒否にする場合。

.htaccess


<Files xmlrpc.php>
Order allow,deny
Deny from all
</Files>
<Files wp-config.php>
Order allow,deny
Deny from all
</Files>
<Files license.txt>
Order allow,deny
Deny from all
</Files>
<Files wp-comments-post.php>
Order allow,deny
Deny from all
</Files>

必須 : 管理画面への不正ログインを防ぐ

管理画面への不正ログインを防ぐために、以下の手段がある。

  1. ログイン時に使うユーザー名とメールアドレスを表示しない:必須
  2. BASIC認証を設定する
  3. ログインページのURLを変更する
  4. 記事投稿は編集者権限で行う

1. ログイン時に使うユーザー名とメールアドレスを表示しない

意外と見落としがちなのがユーザー名やメールアドレスが表示されていることだ。管理画面へのログインにはユーザー名または メールアドレス、そしてパスワードが求められる。このうちの一つが分かっている状態であると、管理画面への不正ログインが容易になる。

STEP1 : ユーザー名ではなくニックネームを表示する

WordPressのユーザー設定画面

デフォルトのままであれば、WordPressのユーザー名は投稿者名としてサイト上に表示される。[ユーザー]のプロフィール設定画面で、ユーザー名とニックネームは別にし、表示をニックネームにしておく。ニックネームは短く親しみやすいもので構わないが、ログインに使うユーザー名は推測されにくいものを用意しよう。

STEP2 : メールアドレスを分ける

サイト上に連絡先としてメールアドレスを表示する場合は、ログイン時に使用されるメールアドレスと別のものを使おう。

2. BASIC認証を設定する

BASIC認証
指定ページにアクセスする時にユーザー名とパスワードを求めるシステムのこと。ユーザー名とパスワードを間違えた場合はそのページにアクセスできなくなる。

BASIC認証をWordPressの管理画面ページとログインページにかけることで、二重に鍵が掛かっている状態となる。

レンタルサーバー会社によっては非常に簡単に導入できるので、お使いのサーバー会社の公式サイトを参考にしてほしい。

XSERVER : https://www.xserver.ne.jp/manual/man_server_limit.php

さくらのレンタルサーバー : https://help.sakura.ad.jp/hc/ja/articles/206207041-ファイルマネージャーでアクセス制限をする

ロリポップ!レンタルサーバー : https://lolipop.jp/manual/hp/htaccess-02/

基本的な手順

サーバー会社のサービスが利用できない場合は、以下の手順を参考にしてもらいたい。

  1. .htaccessに記述
  2. .htpasswdファイルを作成
  3. ユーザー名と暗号化したパスワードを作成
  4. ディレクトリにあげる

3. ログインページのURLを変更する

WordPressのログインページはインストール時のままであれば、https://.../wp-login.phpにある。このことはウェブサイトの知識がある者なら誰でも知っている。なので、ログインページのURLは推測されにくい任意のURLに変更すべきだ。

WordPressのログインページのURLを変更する手段は主に3つある。

  • 手段1:WordPressのプラグインを使用する。
  • 手段2:新ファイルを作成し、function.phpを編集する。
  • 手段3:.htaccessファイルを編集する。

手段1:WordPressのプラグインを使用する。

ログインページのURLを変更できるWordPressのプラグインはいくつかある。

多くのプラグインで、設定によって還元に任意のURLを設定できる(例:.../wp-login-example.../wp-custom-login)。

ただ、プラグイン自体のセキュリティーを考慮するとおすすめしない。

手段2:新ファイルを作成し、function.phpを編集する。

手段1と同様、手段2の場合も完全に任意のURLを設定できる(例:.../wp-login-example.../wp-custom-login)。

具体的な方法は以下の記事が分かりやすいと思われる。

 

有限会社 エス技研『WordPressの管理画面ログインURLの変更方法解説』:https://blog.s-giken.net/140.html

手段3:.htaccessファイルを編集する。

管理人は手段3を推奨する。

手段3の場合、URLの形は.../wp-login.php?任意の数字・アルファベットとなる(例:.../wp-login.php?dggou3432.../wp-login.php?124924)。

 

.htaccessに以下のコードを記述すれば設定できる。

.htaccess


RewriteRule ^enter/?$ /wp-login.php?任意のアドレス [R,L]
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
RewriteRule ^dashboard/?$ /wp-login.php?任意のアドレス&redirect_to=/wp-admin/ [R,L]
RewriteRule ^dashboard/?$ /wp-admin/?任意のアドレス [R,L]
RewriteRule ^register/?$ /wp-login.php?任意のアドレス&action=register [R,L]
RewriteCond %{SCRIPT_FILENAME} !^(.*)admin-ajax\.php
RewriteCond %{HTTP_REFERER} !^(.*)example.com/wp-admin
RewriteCond %{HTTP_REFERER} !^(.*)example.com/wp-login\.php
RewriteCond %{HTTP_REFERER} !^(.*)example.com/enter
RewriteCond %{HTTP_REFERER} !^(.*)example.com/dashboard
RewriteCond %{HTTP_REFERER} !^(.*)example.com/register
RewriteCond %{QUERY_STRING} !^任意のアドレス
RewriteCond %{QUERY_STRING} !^action=logout
RewriteCond %{QUERY_STRING} !^action=rp
RewriteCond %{QUERY_STRING} !^action=register
RewriteCond %{QUERY_STRING} !^action=postpass
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
RewriteRule ^.*wp-admin/?|^.*wp-login\.php /not_found [R,L]
RewriteCond %{QUERY_STRING} ^loggedout=true
RewriteRule ^.*$ /wp-login.php?任意のアドレス [R,L]

任意のアドレスには任意の文字列を入れる(例:.../wp-login.php?dggou3432.../wp-login.php?124924)。

example.comには、サイトのドメインを入れる。

 

例)example.comサイトのログインページのURLを.../wp-login.php?124924にする場合。

.htaccess


# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

RewriteRule ^enter/?$ /wp-login.php?124924 [R,L]
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
RewriteRule ^dashboard/?$ /wp-login.php?124924&redirect_to=/wp-admin/ [R,L]
RewriteRule ^dashboard/?$ /wp-admin/?124924 [R,L]
RewriteRule ^register/?$ /wp-login.php?124924&action=register [R,L]
RewriteCond %{SCRIPT_FILENAME} !^(.*)admin-ajax\.php
RewriteCond %{HTTP_REFERER} !^(.*)example.com/wp-admin
RewriteCond %{HTTP_REFERER} !^(.*)example.com/wp-login\.php
RewriteCond %{HTTP_REFERER} !^(.*)example.com/enter
RewriteCond %{HTTP_REFERER} !^(.*)example.com/dashboard
RewriteCond %{HTTP_REFERER} !^(.*)example.com/register
RewriteCond %{QUERY_STRING} !^124924
RewriteCond %{QUERY_STRING} !^action=logout
RewriteCond %{QUERY_STRING} !^action=rp
RewriteCond %{QUERY_STRING} !^action=register
RewriteCond %{QUERY_STRING} !^action=postpass
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
RewriteRule ^.*wp-admin/?|^.*wp-login\.php /not_found [R,L]
RewriteCond %{QUERY_STRING} ^loggedout=true
RewriteRule ^.*$ /wp-login.php?124924 [R,L]
</IfModule>
# END WordPress
メモ

Q : URLを変更したらXserverのWordPressセキュリティー設定(ログイン試行回数制限設定)が無効にならないか?

A : 無効にならない。

WordPressはログイン時にwp-login.phpというファイルを使う。XserverのWordPressセキュリティー設定では、このwp-login.phpにアクセスがあったかどうかを基準に動作する。なので、手段1から手段3のいずれの方法でも、各設定が無効になることはない。(問い合わせ済み)また、変更先のURLでもBASIC認証は無効にならなので、3重で鍵をかけている状態となる。

4. 記事投稿は編集者権限で行う

万が一、不正ログインの被害にあった時のために、常日頃から管理者権限ではなく編集者権限でログインし、記事の投稿を行った方がよい。これには、管理画面への不正ログインを許したときの被害を最小限に抑える効果がある。

具体的に管理者権限で不正ログインを許した場合、WordPressの設定画面やユーザー設定の変更や、重要ファイル(WordPressテーマ、プラグイン、.htaccess)へのアクセス・改ざんが可能になる。

編集者権限では、サイトのテーマ・プラグインの追加/編集など重要な画面にアクセスできない。多少面倒ではあるが、普段から実施しておくと良い。

推奨 : WordPressサイト自体のセキュリティを上げる

次にサイト自体のセキュリティーを上げる。ここからは段階を踏むごとに専門的になっていく。

Observatory by Mozillaのセキュリティーチェック

はじめに、Observatory by Mozillaで所有サイトのセキュリティーレベルを確認してほしい。

Observatory by Mozilla : https://observatory.mozilla.org/

Observatory by MozillaのStaticsのグラフのとおり、ほとんどのWordPress構築のサイトが最下位のEランク以下になる。アメリカの政府機関のウェブサイトですら、D~Fランクに位置している。デフォルトのままで対策していないWordPressサイトであれば確実にFランクになる。

厳密に言うと、項目によっては設定しなくても良いと思われる項目もある。しかし、管理人は、あらゆる状況を想定してセキュリティーレベルを高く維持することを方針としている。ここから先は、Observatory by Mozillaを基準に設定していく。

手順

以下の手順で、セキュリティーレベルを上げていく。

  1. HTTP Strict Transport Security (HSTS)
  2. X-Frame-Options
  3. X-Content-Type-Options
  4. Content Security Policy
  5. Refferer Policy
  6. Subresource Integrity

STEP1: HTTP Strict Transport Security (HSTS)

HTTP Strict Transport Security (HSTS)
ユーザーがexample.comでアクセスした場合を想定して、ブラウザにhttp://ではなくhttps://で通信するようにサイトから指示する機能。この設定せずに常時SSL化しているサイトでは、example.comでアクセスした時、一旦http://で接続したのち、https://にリダイレクトされる。この場合、安全な公式サイトにリダイレクトされるまでに、攻撃者が悪意あるサイトにリダイレクトされる恐れがある。

SLL Labs(https://www.ssllabs.com/ssltest/)の判定が、A+でなかったサイトは、以下の手順を踏めばA+になる。
.htaccessファイルに以下のコードを記述する。

.htaccess


Header set Strict-Transport-Security "max-age=315360000; includeSubDomains; preload"

HTTP Strict Transport Security (HSTS)についての詳細は、以下の記事にある。

MDN web docs『HTTP Strict Transport Security』https://developer.mozilla.org/ja/docs/Web/Security/HTTP_Strict_Transport_Security

STEP2 : X-Frame-Options

X-Frame-Options
サイトのコンテンツが外部のサイトに<frame><iframe><object>を通して表示されないように制御する機能。設定してない場合は、<frame><iframe><object>を通しての表示を許可している状態となる。設定項目は3つあり、DENYでは自身のドメインを含む全てのドメインで表示ができなくなる。SAMEORIGINでは自身のサイトでのみ表示が許可される。ALLOW-FROM https://example.com/は指定したドメインのみ表示を許可する。

 

沢山のユーザーを抱えるウェブサービスであれば、適切に設定しなければならない。情報提供を基本とするWordPressサイトであれば、設定しなくてもよいだろう。念のため設定したい場合、DENYか、使用しているプラグインによっては、SAMEORIGINに設定した方が良い。

.htaccessファイルに以下を記述。

例)SAMEORIGINで設定する場合。

.htaccess


Header set X-Frame-Options SAMEORIGIN

STEP3 : X-Content-Type-Options

X-Content-Type-Options
ブラウザがContent-Typeを無視して自動でファイルのタイプを判断することを制御する機能。nosniffに設定することで、意図していないファイルの実行を防ぐ。

.htaccessファイルに以下を記述。

.htaccess


Header set X-Content-Type-Options: nosniff

STEP4 : Refferer Policy

Refferer Policy
リファラー情報を制御する機能。通常、ユーザーがサイトAからサイトBに移動した時、リファラー情報としてサイトAのURLがサイトBに送られる。リファラー情報を送りたくない場合(例:URLにプライバシーに関わる情報が含まれている場合)やリファラー情報を送りたい場合(例:ユーザーの動向分析したい場合)に合わせて細かく設定できる。

 

設定項目についての詳細は以下の記事を参照。

MDN web docs『Referrer Policy』https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Referrer-Policy

 

当サイトではstrict-originまたは、strict-origin-when-cross-originを推奨する。

 

例)strict-originで設定する場合

.htaccess


Header set Referrer-Policy: strict-origin

STEP5 : Content Security Policy

Content Security Policy
サーバー側でスクリプトのホワイトリストを作成することで、サイト上で実行するスクリプトファイルやインラインの<sctipt>要素やhtml属性のイベントハンドラ(<div onclick="..">など)を制御する機能。ホワイトリストに含まれないスクリプトのコードは無視される。

コンテンツセキュリティーポリシー(Content Security Policy:CSP)に関してはかなり骨の折れる作業だ。効果は強力だが、サイトの運営方法によっては、導入は不可能。WordPress自体が設計上インラインスクリプトを使っているため、WordPressと相性が悪いので、実施しない方が良いかも。なので、無視して良い。

しかし、以下の記事では多少強引めに導入する方法を紹介する。

STEP6 : Subresource Integrity

Subresource Integrity
CDN上にあるファイルをサイトに読み込む際に、<script>要素にハッシュの値(integrity="ハッシュ値")をつけることで、使用ファイルがそのハッシュ値と一致するかを検証し、使用ファイルが改竄されていないことを確認する機能。

Subresource Integrityに関しては設定しておけば安心。

以下の記事で詳しく説明している。

ここでは簡易な説明にとどめる。

手順

  1. SRI Hash Generatorでshaの値を調べる。
  2. function.phpファイルでファイル管理。

該当ファイルのURLを記入。

SRI Hash Generator: https://www.srihash.org

function.phpで設定すれば良いだけなので、WordPressのテーマを作成する知識があれば簡単にできる。

function.php


add_filter( 'script_loader_tag', 'add_attribs_to_scripts', 10, 3 );
function add_attribs_to_scripts( $tag, $handle, $src ) {

$barba = array(
    'barba'
);

if ( in_array( $handle, $barba ) ) {
    return '<script src="' . $src . '" integrity="SRI Hash Generatorで得た値をここに記載" crossorigin="anonymous" type="text/javascript"></script>' . "\n";
}

return $tag;
}

ページのソースを表示して、該当のスクリプトタグが以下のようになっていれば完了。

index.html


<script src="#" integrity="SRI Hash Generatorで得た値" crossorigin="anonymous" type="text/javascript"></script>

STEP3、4、5、7のコードをまとめると以下の通りになる。Content Security Policy とSubresource Integrity に関しては、直接サイトのプラグインやテーマのコードを読んで、導入できそうなら導入すればよい。

.htaccess


#HTTP Strict Transport Security
Header set Strict-Transport-Security "max-age=315360000; includeSubDomains; preload"

#set X-Frame-Options
Header set X-Frame-Options DENY

#X-Content-Type-Options
Header set X-Content-Type-Options: nosniff

#Referrer-Policy
Header set Referrer-Policy: strict-origin

おわりに

以上の設定はサイト設計や環境に大きく依存する。本記事の内容は管理人のサーバー環境で実行したことをまとめたものだ。実行する際は、自己責任でお願いしたい。現時点でカバーできていない対策や、新たに対策すべきものは今後随時更新していく。

更新履歴

2018-08-03 『WordPressサイトのセキュリティー向上のノウハウ』をテーマに記事作成

 

[rns_reactions]
.
スポンサーリンク

商用利用可な素材配布しています!!

商用利用可なフリー素材ULOCO商用利用可なフリー素材ULOCO