最近のレンタルサーバーではドメイン登録後無料でSSL証明書が適用され、サイトがSSL通信に対応するようにできるようになっているところが増えています。
SSL通信に対応しているかどうかは単純に言えば「https://~」でサイトが表示できるかどうかで判別できます。表示できない場合はSSL通信に対応していません
SSL通信が確立できているサイトで考えたいのが、すべてのページへの接続をSSL通信で確立すること(平たく言えばhttp://~のアクセスをhttps://~でアクセスさせるようリダイレクトをすること)による通信セキュリティのアップと、HSTS(セキュリティヘッダー)をHTML上に出力してさらにセキュリティアップを図ることです。
どちらもWordPressがインストールされているディレクトリの.htaccessファイルへ追記することで実現できるのですが、今回は有効化しているテーマのfunctions.phpへ追記することでファイルへ直接記述せずに対処してみようというアプローチを紹介します。
SSL通信へのリダイレクト(常時SSL通信の確立)については本ページの主旨から外れるため割愛します。もしも確立できていない場合はページ後半の「functions.phpから常時SSL通信を確立する方法」を先にご覧ください
functions.phpからHSTSを追加する方法
いきなりですが、以下を有効化しているテーマのfunctions.phpへ追加することで実装できます。
function pwcn_pagely_security_headers( $headers ) {
//$headers['X-Frame-Options'] = 'SAMEORIGIN';//古いブラウザ用なのでコメントアウト
$headers['X-Content-Type-Options'] = 'nosniff';
$headers['X-XSS-Protection'] = '1;mode=block';
$headers['Referrer-Policy'] = 'no-referrer-when-downgrade';
$headers['Content-Security-Policy'] = "frame-ancestors 'self'";
$headers['Strict-Transport-Security'] = 'max-age=31536000;includeSubDomains; preload';
$headers['Cross-Origin-Resource-Policy'] = 'same-origin';
$headers['Cross-Origin-Opener-Policy'] = 'unsafe-none';
//Content-Security-Policyをフィルターで変更可能にする
// デフォルトではすべてのドメインを許可
$default_policy = "frame-ancestors 'self' https://*";
// フィルターフックを使ってポリシーを変更できるようにする
$policy = apply_filters( 'pwcn_pagely_frame_ancestors_policy', $default_policy );
$headers['Content-Security-Policy'] = $policy;
$headers['Cross-Origin-Embedder-Policy'] = 'unsafe-none';
$headers['Permissions-Policy'] = 'geolocation=(), midi=(),sync-xhr=(),accelerometer=(), gyroscope=(), magnetometer=(), payment=(), camera=(), microphone=(),usb=(),fullscreen=(self)';
return $headers;
}
/*** 一応SSLでなかったら発火しないようにする ***/
if (!empty($_SERVER['HTTPS'])) {
add_filter( 'wp_headers', 'pwcn_pagely_security_headers' );
}
X-Frame-Optionsについては最新のブラウザでは必要ないのでコメントアウトしています
ヘッダー上に出力する各機能(コード中の行)については詳しく書きませんのでご自身でお調べください
問題なく追加できたら、次項で紹介する方法できちんとセキュリティヘッダーが機能しているかを確認ください。
HSTSの設定確認
セキュリティヘッダーで出力されている内容や、正常に機能しているかは以下のサイトでで確認できます。
例えば、上の検証ツールで検証した場合、コードを追加する前には、以下のような結果画面が出ます。

要は、Headersという項目にあるものが、必要とされるセキュリティヘッダーの項目で、それらが何も設定されていませんよ!という表示です。
コード追加後に再確認すると以下のように「A」判定の結果が返ってきます(実際の画像と若干異なります)。

こうなれば設定は完了です。
本来は「A+」となるのが理想であるものの、コードのところで書いた通り、旧ブラウザ用の「X-Frame-Options」を抜いているので「A」判定になりますが、機能としては全く問題ありません。
コードの注意点
1点、コード中の以下の部分に注目します。
//Content-Security-Policyをフィルターで変更可能にする
// デフォルトではすべてのドメインを許可
$default_policy = "frame-ancestors 'self' https://*";
// フィルターフックを使ってポリシーを変更できるようにする
$policy = apply_filters( 'pwcn_pagely_frame_ancestors_policy', $default_policy );
$headers['Content-Security-Policy'] = $policy;
この「Content Security Policy(CSP)」という項目は、自ドメインや他のドメインからコンテンツの一部を取得しようとしたときにどのように振る舞うのかを指定するものです。
これがWordPressで関連するのが段落ブロックなどに挿入したURLを自動でカード化する機能で、自ドメインのみアクセスを許可するという意味の「self」のみにした場合には、他のドメインのサイトからの情報取得を受け付けず、カード化されません。
そこで上記コードでは、何も指定しなければ「self」と「https://*」というSSL通信しているサイトからのアクセスすべてを許可するようにしています。
こうすることで、他のサイトでページのURLのみを入力した場合に何もしなくてもカード表示されるようになります。
ただこれはセキュリティ上あまり好ましいことではなく、本来はアクセスできるドメインを限定するのが妥当です。
もしもセキュリティをより強固にしたい、自ドメインのみ許可したいという場合のために、以下の行で変更ができるようにしています。
$policy = apply_filters( 'pwcn_pagely_frame_ancestors_policy', $default_policy );
実際に変更したい場合には、以下のコードをfunctions.phpへ追加します。
function pwcn_allow_csp_domain_filter($policy){
// 許可するドメインの配列
$allowed_domains = [
//ここに許可するドメインを追加
//例:'https://example.com',
];
// 配列を文字列に変換
$domains_string = implode(' ', $allowed_domains);
// ポリシーを更新
return "frame-ancestors 'self' $domains_string";
}
add_filter( 'pwcn_pagely_frame_ancestors_policy', 'pwcn_allow_csp_domain_filter' );
このコード内の「ここに許可するドメインを追加」の部分へ許可するドメインを列記すればそのドメインと自ドメインが許可され、何も指定しなければ自ドメインだけが許可されるようになり、セキュリティアップを図ることができますから、必要であれば追加して設定してください。
以上functions.phpからセキュリティヘッダーを追加する方法でした。
コードの作成にあたっては以下のページなどを参考にしました。
- 「Boost WordPress Security by Adding Essential Headers through functions.php」
- Adding Security Headers to WordPress Without 3rd-Party Plugins
functions.phpから常時SSL通信を確立する方法
セキュリティヘッダーは常時SSL通信させているサイトでないと意味がありませんので、補足としてテーマのfunctions.phpから常時SSL通信化(SSL通信への常時リダイレクト)を行う方法を紹介しておきます。
以下のコードを有効化しているテーマのfunctions.phpへ追加します。
function ssl_redirect_add_to_htaccess( $rules ) {
$content = <<<EOD
#<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
EOD;
return $content . $rules;
}
add_filter('mod_rewrite_rules', 'ssl_redirect_add_to_htaccess');
コードを追加したら、管理画面の「設定」→「パーマリンク」をクリックして開き、何もしないで「変更を保存」をクリックして、リライトルールをフラッシュしてください
上記コードはレンタルサーバーで稼働するwebサーバーソフトウェアが「apache」またはそれに準拠する場合に有効なコードです。その他の場合には動作しないことがありますのでご注意ください
参考:Help Code Review – I need to write on .htaccess file from theme’s function.php
コメントを残す