WordPressを完全にSSLへ移行してみた

うちのサイトは証明書の関係でPreload HSTS(HTTP Strict Transport Security)にはしていないけれど、
HSTS設定前でもかなりhttpsからのアクセスがあったのでHSTSの設定をして、常にhttpsへ接続してもらうようにました。

で、2017年1月にリリース予定のChromium 56から、パスワードやカード情報を送信するhttpなサイトは「安全ではない」と表示するようになるようです。
Chromium Blog: Moving Towards a More Secure Web

HTTP/2.0になって完全にhttpは要らないんじゃ?って感じになってきてるみたいですね。

もうそれなら完全にSSLへ移行しちゃって良いんじゃないかー!って事で、httpをhttpsへ301でリダイレクトするようにしました。
方法はいろいろあるけれど、WordPressならrewriteで良いと思う。

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://blog.wolfs.jp$1 [R=301,L]

ちなみに、RewriteRuleのURLで最後にスラッシュを入れるとリダイレクト先でダブルスラッシュになるので注意。
例:
 RewriteRule: RewriteRule ^(.*)$ https://blog.wolfs.jp/$1 [R=301,L]
 アクセスURL: http: //blog.wolfs.jp/page-1/
 リダイレクトURL: https: //blog.wolfs.jp//page-1/

これの何が悪いかと言うと、
ダブルスラッシュになっているとWordPressのリダイレクトが働いてhttps://blog.wolfs.jp/page-1/へリダイレクトされるので合計2回リダイレクトされる事に。
かなり無駄なので注意。
RewriteBase /なんかを使うと良いけど、別にそんなの指定しなくても/を1つ抜くだけで動くから要らないとおもうw

この状態でMozillaが提供しているサイトのセキュリティ診断、Observatory by Mozillaをうけてみると・・・
Observatory 結果
うんA+でかなり良いスコアがでました。
続きを読む »

WordPressのインラインJavaScriptをなくして、Content Security Policyを設定

うちのテーマは今のこのデザインになるまでは、サードパーティーのテーマを使っていたんです。
で、そのテーマには脆弱性があってXSSが有効だったんですよー((゜Д゜;))

今は1から作った独自のテーマを使っていて、汎用的な拡張性(テーマに必要な画像等のアップロード機能やAJAX)や外部を参照する不明なコードはありません。
なのでテーマ経由の脆弱性はない感じなのです。

だけれど、XSSを防ぐセキュリティ関連のヘッダーを設定しておいた方が良いって事なのでApacheにヘッダーを追加してみました。
新しく追加したのはX-Content-Type-Options、X-XSS-Protection、Content-Security-Policyの3つで、どれもXSSを防ぐのに効果が高いもの。
X-Frame-Optionsだけはブログをiframeで表示されていたサイトがあったので設定済みでしたw

設定内容はこんな感じ。

Header always set X-Frame-Options SAMEORIGIN
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set Content-Security-Policy "default-src 'self' *.wolfs.jp; script-src 'self' *.wolfs.jp; child-src 'self' data: www.youtube.com; style-src 'self' 'unsafe-inline' *.wolfs.jp; img-src 'self' data: *.wolfs.jp *.gravatar.com;"

 
で、今回躓いたのはContent Security Policy(CSP)の設定。

JavaScriptやCSSは以前から1つにまとめているので大した問題ではなかったのですが、CSPで「script-src 'self' *.wolfs.jp」のようにインラインスクリプトを許可しない設定だとWordPressが出力するコメント関連のスクリプトが動かなくなっちゃう。
かと言って許可するとXSSに対して弱くなり、CSPを設定しないのとあまり変わらないような結果になります。

うちの環境で見た感じ、主にWordPressが出力するインラインJavaScriptは、
 ・コメントフォームの隠しフィールド「_wp_unfiltered_html_comment_」
 ・コメントのある「返信」ボタンのonclick
のようです。

とりあえず、その辺を無効化して無効化した物を再度使用可能にするように作っていきます。
続きを読む »

WordPress 4.6で追加されたdns-prefetchを無効化する

WordPress 4.6からヘッダーに<link rel="dns-prefetch" href="//s.w.org/">が追加されるようになりました。
見つけた瞬間サイトがクラックされたのか?!とヒヤっとしたけれど、s.w.orgはWordPressのショートドメインて事がわかって一安心しましたw

うちはWordPressの絵文字とかを使っていないのでs.w.orgのDNSプリフェッチは必要なし。
なのでこれを無効化してみました。

作成したPHPコードはこれ。

<?php
 
add_filter('wp_resource_hints', function ($urls, $relation_type) {
    if (is_admin() === false) {
        if ($relation_type === 'dns-prefetch') {
            return array();
        }
    }
 
    return $urls;
}, 10, 2);
 
?>

コードは簡単でwp_resource_hintsにフィルターをかけて、管理ページ以外かつタイプがdns-prefetchの場合は定義されている内容を空っぽにして返すって感じ。
管理ページの場合は、なにかあるとダメなので引数をそのまま返すようにしてあります。

全く使わないならremove_action('wp_head', 'wp_resource_hints');の方がはやいんじゃない?って思ったんだけど、なぜかこれが効かなかったのでadd_filterで対処する荒療治に。

ちなみに、この記事を書いた時の$relation_typeの種類はdns-prefetch、preconnect、prefetch、prerenderとありました。
詳しい動作を追いたい場合はwp-includes/general-template.phpの2800行付近にfunction wp_resource_hints()があるのでそこから見てください。

archive.isにアーカイブされたページで警告を表示する。

archive.isをブロックしたりして対策をしてもアーカイブされちゃう事があります。
その対策の間をぬってアーカイブされちゃったページに警告を表示するJavaScriptを作ってみました。

if (location.hostname != "yourdomain") {
    document.title = "[不正コピー]";
    document.getElementsByTagName("body")[0].innerHTML = "";
 
    var i, html = "";
    for (i = 0; i <3000; ++i) {
        html += "/// 不正コピーです! /// ";
    };
    document.getElementsByTagName("body")[0].innerHTML = html;
    html = null;
};

コードは簡単、location.hostnameを比較してyourdomain以外なら警告を表示するコードを実行するだけ。
動作内容はタイトルを「[不正コピー]」に変更し、BODYエレメント内容を全部削除し代わりに「/// 不正コピーです! ///」の文字を3000回並べます。
yourdomainはあなたのサイトのドメイン名に変更して下さい、変更しないと本物のサイトでこのメッセージが表示されて悲惨なことになりますw

JavaScriptなので当然JavaScriptを動作しないようにしてある環境では動きませんが、現在はJavaScriptが動かない環境の方が少ないのである程度の効果はあると思います。

序で・・と言ったらあれですが・・
この文字を表示する動作を重くしたい場合は以下のようにコードを変更するだけ。

if (location.hostname != "yourdomain") {
    document.title = "[不正コピー]";
    document.getElementsByTagName("body")[0].innerHTML = "";
 
    for (var i = 0; i <3000; ++i) {
        document.getElementsByTagName("body")[0].innerHTML += "/// 不正コピーです! /// ";
    };
};

これは文字が追加される毎にDOMのレンダリングが発生するのでレンダリング負荷が増えます。
低スペックのPCやモバイル端末ではクラッシュさせる事もできるかも。
本当に重くさせるのであれば無限ループ化すればOK。

ちょっと応用すればarchive.isのロボットを狙い撃ちでクラッシュさせアーカイブを中断させる事も可能です。

Twitterにアップされている動画のTSファイル一覧を表示&保存する

Twitterにアップされている動画で保存したい物があったので、HTTPリクエストログからURLをゲットしようとおもったら・・・
なんとm3u8の再生リスト形式になっていて動画自体も.tsに分割されていました。

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=320000,RESOLUTION=240x180,CODECS="mp4a.40.2,avc1.42001f"
/ext_tw_video/.../pu/pl/240x180/???.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=832000,RESOLUTION=480x360,CODECS="mp4a.40.2,avc1.42001f"
/ext_tw_video/.../pu/pl/480x360/???.m3u8
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:3
#EXTINF:3.000,
/ext_tw_video/.../pu/vid/0/3000/480x360/???.ts
#EXTINF:3.000,
/ext_tw_video/.../pu/vid/3000/6000/480x360/???.ts
#EXTINF:3.000,
/ext_tw_video/.../pu/vid/6000/9000/480x360/???.ts
#EXTINF:3.000,
/ext_tw_video/.../pu/vid/9000/12000/480x360/???.ts
#EXTINF:3.000,
/ext_tw_video/.../pu/vid/12000/15000/480x360/???.ts
....

再生リストから欲しいサイズの動画を選んで分割ファイルをダウンロードすれば良いんだろうけど面倒くさいw
それに、分割は3秒毎なので2分を超える動画は70ファイル超え!

そんなの1つずつURLをコピペなんてやってられない・・って事で、動画サイズ毎のURLとファイルを一覧表示するGreasemonkeyスクリプトを作ってみました。
動作してる動画はこちら。

1ファイル毎に手動保存なのはローカルに自動でファイルを保存するAPIが呼び出せないから。
userChrome.jsとして動かせばできるんだけど、セキュリティ的にあまり宜しくない。

まあ随分と楽になるんじゃないかなーと。
保存時にはINDEXに表示されている番号と同じファイル名にしないと、TSファイルの連結時に時系列がごちゃごちゃになりますw

おまけ?として法人など業界用の動画VMAP形式の動画も落とせるようにしました。
分割されていないので楽ちんですw
続きを読む »