WordPress をさらに安全にするための HTTP セキュリティヘッダーまとめ

今年になってから常時 SSL が本格的に普及し始めました。

この流れは誰もがインターネットを安全に利用できるようにしようという趣旨なんですが、来訪者の安全を守るためにみなさんが対策可能なことは他にもたくさんあります。

ここで紹介する各種のレスポンスヘッダーは、もし XSS などの脆弱性があった場合でも、来訪者がその影響をうけないように、このサイトはこういうポリシーでできてるから、それにマッチしないコンテンツは実行しないで!とあらかじめ来訪者のブラウザにお知らせすることで、来訪者の安全を守るためのものです。

根本的には、WordPress をつねに最新版に保つ、プラグインやテーマは信頼できるものを使用するなどの一般的な対策が別途必要なので誤解のないようにお願いいたします。

X-XSS-Protection

以下のようなレスポンスヘッダーを出力することで、ブラウザの XSS フィルター機能を強制的に有効化することができます。

通常、対応ブラウザではデフォルトで有効になっていますが、ユーザーが設定でオフにしている場合に、このヘッダーを出力することで強制的にオンになります。

X-XSS-Protection: 1; mode=block

ヘッダーの値  1; mode=block は、他にもありますので自力で調べてください。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection

このレスポンスヘッダーを WordPress で出力をするなら以下のような記述を自作プラグインに記述してください。

add_action( 'send_headers', function() {
    header( 'X-XSS-Protection: 1; mode=block' );
} );

HTTP Strict Transport Security

HTTP Strict Transport Security (以下HSTS)は、そのサイトが HTTPS で接続すべきであることをブラウザにあらかじめ知らせるための仕組みです。

https://developer.mozilla.org/ja/docs/Web/Security/HTTP_Strict_Transport_Security

このレスポンスヘッダーを使用すると来訪者のブラウザは、次回アクセス以降に直接 HTTPS のURL にアクセスすることを試みるようになります。

また、HSTS プリロードを申請すれば、初めての来訪者も HTTPS で接続を試みるようになります。

以下の例は、HSTS の有効期限を1年、プリロードを有効化した場合のレスポンスヘッダーの例です。

add_action( 'send_headers', function() {
    header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' );
} );

 とても大切なことなので、太字で書きますが、このヘッダーをその気がないのに(常時SSLを導入する気がない等)導入するとその有効期限内は、そのサイトにアクセスできなくなる可能性があります。

HSTSのプリロードの申請は以下の URL で可能です。

https://hstspreload.org/

X-Frame-Options

X-Frame-Options は、クリックジャッキング攻撃という攻撃手法を防ぐためのヘッダーです。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

クリックジャッキング攻撃とは、ターゲットとなるウェブサイトを iframe 内に表示し、上に透明化されたボタンを設置する等の方法で、来訪者が意図したものとは違うものをクリックさせる攻撃手法のことです。

以下のように指定することで、みなさんのサイトが第三者のサイトの iframe 内に表示されることを防ぐことができます。

add_action( 'send_headers', function() {
    header( 'X-Frame-Options: DENY' );
} );

または

add_action( 'send_headers', function() {
    header( 'X-Frame-Options: SAMEORIGIN' );
} );

WordPress は、このヘッダーがログイン画面及びダッシュボード内ではデフォルトで出力されています。

Content-Security-Policy

Content Security Policy (CSP) とは、みなさんがウェブサイトに表示するコンテンツに関するポリシーをヘッダーであらかじめブラウザに通知し、それにマッチしないコンテンツを表示しないようにするためのものです。

https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

具体的には、

  • このサイトは、*.example.com という CDN から、JavaScript をロードしているけど、それ以外から読み込んでたら無視して!
  • このサイトは、インラインの JavaScript は一切使ってないからもしあっても実行しないで!
  • このサイトは、同じドメインの画像しか使ってないはずなので、よそのドメインの画像は表示しないで!

などのような感じです。

このヘッダーは XSS 脆弱性を防ぐための決定版としてとても有効な対策なのですが、実際にこのヘッダーで有益なセキュリティ対策を施すにはWordPress ではいくつかの問題があります。

管理画面における問題点

WordPress は管理画面においてインライン JavaScript を使用しており、これらは後方互換性のために今後も使用されます。

したがって、CSP を導入する際には以下のような条件分岐で、管理画面を除外する必要があります。

if ( ! is_admin() ) {
    ....
}

この件については、WordPress の開発チームでもディスカッションされたことが数回ありますが、現状は管理画面でCSPを使用することはほぼ不可能であると言えます。

ウェブサイト側の問題点

来訪者を保護するという観点では、管理画面はとりあえずあきらめて、ウェブサイト側のみ有効化するということもできます。

しかし、それでもいくつかの問題点があります。

  • 絵文字を古いブラウザで表示するためのインライン JavaScript を WordPress がデフォルトで出力するので、それを無効化する必要がある。
  • Google Analytics のコードを外部ファイル化する。
  • JetPack の Site Stats を無効化する。(他の機能もあるかも。。。)

さらに一部の JavaScript に依存する WordPress プラグインでは、JavaScript が出力するテキストのローカライゼーションに wp_localize_script() という関数を使用しています。

この場合もインラインの JavaScript が出力されますので、独自のプラグイン等で外部ファイル化するなどして、インライン JS を止める必要があります。

以上のように、CSP を導入する際にはこれらの問題を改善する必要がありますが、ウェブサイト側では決して不可能なものではなく、むしろ自分のサイトがどこからどんなリソースをロードしているかを把握し、それらをうまくコントロールすることはセキュリティ上とても有益なものとなりますので、挑戦してみる価値はあると思います。

まとめ

今回の記事では、効果が大きそうな代表的なものを紹介しましたが、他にもいろいろあります。

今年になって SSL の導入が活発化したことがきっかけなのか、僕のところにくる案件でこれらのヘッダーに対する対応を求められるケースがちらほらでてきており、CSP を導入している WordPress サイトもあります。

以下のサイトでは、これらのヘッダーの導入状況を評価してくれますので、ぜひみなさんのサイトで試してみましょう。

https://observatory.mozilla.org/analyze.html?host=capitalp.jp

 

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください