みんなのウェディングのウェブサービスを完全HTTPS化した流れを紹介!

こんにちは、技術部の坪井です。(みんなのウェディング)を2017年6月13日に完全HTTPS化しました。私達が行った完全HTTPS化の対応をご紹介します。

何故完全HTTPS化を行うのか

昨今インターネットの流れとして完全HTTPS化が進んできています。Webサイトの信頼性を高め、攻撃者からの盗聴・なりすましを防ぎユーザの個人情報を保護することが非常に重要となってきています。 また、新たなAPIや技術(HTTP/2など)において、HTTP通信化では利用が制限があるものも珍しくありません。

みんなのウェディング社では、既にPartyNoteを始めとした、Brides UP!など、2015年以降にリリースした新規サービスはリリース当初よりHTTPS化に対応しています。しかしながら、メインサービスである、みんなのウェディングは、対応規模が大きいためHTTPS化に踏み切れていませんでした。

これまで、みんなのウェディングでは、ログインフォームやユーザが個人情報を入力するフォームや入力情報の確認画面をHTTPS化していました。通信を暗号化するため、機密性の高い情報を取り扱う箇所のみを暗号化し、画面をHTTPS化する必要があるかどうかは、開発者達の判断に委ねられれていました。どの画面が安全であるべきかという選別をその都度する必要があったため、判断を誤ると事故につながる恐れもあったと考えられます。

また、GoogleがHTTPSページを優先的にインデックスするという発表もしている事から、SEOへの影響も見過ごせないと状況もありました。

新たなる技術への対応とより安心なサイトを目指すべく完全HTTPS化に踏み切りました。

完全HTTPS化実現の流れ

大きな流れとしては以下が挙げられます。

  • HTTPS環境のためのクラウド構成を検討
  • テスト環境の構築
  • アプリケーションのHTTPS対応と動作テスト
  • mixed contentの発見と修正
  • 先行リリース
  • HTTPS化の全体リリース
  • リリース後の対応

HTTPS環境のためのクラウド構成を検討

まずは、完全HTTPS化をどのように実現するか検討します。みんなのウェディングではAWSを利用しています。既存の構成は、HTTPSの処理はELBで終端させ、それ以降の通信は平文で行う構成をとっていました。完全HTTPS化に伴い、クライアントとロードバランサーの間にAWSのCloudFrontを配置し、HTTPリクエストをHTTPSに転送する方法を選択しました。CloudFrontからELB間の通信は、インターネットを通るためHTTPSで通信しています。

みんなのウェディングでは、Perlで作成されたアプリケーションと、Ruby on Rails のアプリケーションが並存しています。現在は、Ruby on Railsへ移行を進めています。リバースプロキシを用いて、リクエストURLからどちらのアプリケーションサーバに振り分けるか判断しています。 Perlアプリケーションでは待受ポートへのアクセスによって、HTTPかHTTPSなのか判断し必要なリダイレクト処理を実施していました。これまで、HTTPとHTTPSの待受ポート毎にlocation設定が必要でしたが、HTTPS化によって必然的にHTTPSのみとなり(待受ポートはHTTPのみ)従来のHTTPS側の設定が不要となり、開発効率の向上へ寄与できました。

テスト環境の構築

リリースする前に不具合を発見し修正するため、テスト環境の構築は必須です。本番に近い構成でテスト環境を作成しました。

ここでは、テスト環境に「test.mwed.jp」を使用することにします。CloudFrontエンドポイントを作成します。CloudFrontでは「Redirect HTTP to HTTPS」を選択し、CloudFrontへHTTPで通信が来た場合はHTTPSへ転送させます。また、代替ドメイン(CNAME)に「test.mwed.jp」を指定します。オリジンサーバとしてELBを設定し、CloudFrontには、ELBには同じSSL証明書を配置します。DNSサーバには「test.mwed.jp」のAレコードにCloudFrontのエンドポイントを設定します。

アプリケーションのHTTPS対応と動作テスト

アプリケーション内での利用する基本となるURLをhttps://www.mwed.jpに、プロトコルをhttpsに統一しました。従来からHTTPS通信を利用しているアプリケーションでは、これだけでも充分に動作すると思います。HTTPS化された状態で従来どおりアプリケーションが正常に動作するかテストを行う必要があります。従来どおりの動作をエンジニアだけでテストするのは難しく、日常的にユーザー目線で利用している担当部門のサポートが不可欠でした。そこでサイトURL一覧を作成し、担当部門の方々にユーザ体験の変化がないか、不具合やJavascriptのエラーが発生していないなかテストを実施してもらいました。HTTPS化以前から存在していた不具合の発見や、ページの必要性について見直す機会をもたらしました。 テストでは大きく以下の3つのポイントで動作テストを実施しました。

  • アプリケーションが正常に動作するか
  • ログがこれまで通り出力されているか
  • mixed contetが発生していないか(後述)

アプリケーションは、HTTPへのリダイレクによるループ、URLによるバリデーション処理でのエラー、プロトコル判定によるリダイレクトなどの事象が発生しましたので、対応を実施しました。HTTPS化してもアプリケーションログが従来通りの形式で出力されているかも確認します。

API疎通確認の実施

アプリケーションの動作テストだけではなく、外部通信を行う外部連携サービスとの疎通確認をする必要があります。 テスト時には、外部から従来HTTPで提供していたAPIに接続できなくなるという事象が発見され、接続元に対応を依頼しました。リリース前に気づいた事で事故は未然に防ぐことができました。接続元のクライアント環境によって、接続できなくなる恐れがあるという事を充分考慮してテストに望む必要があります。自社サービスからも同様に疎通確認を実施し、内部サーバからも問題なく疎通できるか確認も行います。

mixed contentの発見と修正

mixed contentは混合コンテンツとも呼ばれ、HTTPSのページにHTTPで配信されたリソースが含まれている場合、HTTPのコンテンツは攻撃者に読まれたり変更されたりする恐れがあります。 HTTPS対応しているページでは一部が暗号化され一見安全なサイトのように表示されますが、実際はそうではありません。mixed contentが存在した場合、ブラウザによって表示方法は異なりますが、ユーザも一目で分かる形でアドレスバーに表示されるようになっています。

developers.google.com を参考に対応を実施しました。 基本的な修正内容は、HTTPのコンテンツ配信をHTTPSの配信に変更することです。 文字列検索を行い、ソースコード内にあるHTTPリソースへのアクセスをHTTPSに修正します。また、アプリケーション側で動的に生成されるhtml内でHTMLリソースへのURLも見落としがちなので注意が必要です。更に、ユーザが作成するコンテンツの中にもHTTPリソースへのアクセスがある可能性がありますので、データベース内の登録データへも対応が必要となります。 私たちは、文字列検索と並行して作成したURLリストのURL1つ1つで、ブラウザの機能を用いてPCとスマートフォン表示を切り替えながらmixed contentがないかブラウザでもチェックしました。草の根的な活動でしたが、私たちにとっては一番確実な方法だったと思います。

リンク先URLの変更対応

<a href="リンク先URL">のリンク先URLのHTTPS化も重要なポイントです。なぜなら、HTTPSからHTTPページへ遷移した際にはリファラが送信されないからです。この場合、ログにリファラが記録されないため、集計になんらかの影響をを引き起こしてしまう可能性も考えられます。HTTPSページ内にHTTPへのリンクが存在していても、mixed contentとはなりません。アプリケーションの動作に影響が無いため、つい見落としがちなポイントです。自サイトへのリンクがHTTPであればHTTPSへ修正し、また、外部サイトへのリンクも遷移先サイトがHTTPS対応しているならば、HTTPSを指定すると良いでしょう。

先行リリース

HTTPページ内の画像やCSS、JavascriptはHTTPSリクエストでも問題にならないと判断し、HTTPSアクセスに対応完了した時点で順次リリースを実施しました。リリース時に該当リソースが配信されているページURLを、ブラウザのアドレスバーでHTTPSに変更し確認することで、mixed contentが発生していなか確認することができました。

全体リリース

全体リリースでHTTPS化に対応したアプリケーションコードをデプロイし、予め準備していたCloudFrontをELBの前段に配置して、DNSでwww.mwed.jpのAレコードをCloudFrontのエンドポイントに設定するという作業を実施しました。みんなのウェディングでは、全体リリースの段階でステージング環境をHTTPS化対応させ、問題が無いことを確認してから本番環境へリリースしました。

リリース後の対応

HTTP Strict Transport Security(HSTS)を有効にする

HTTP Strict Transport Securityは、ブラウザに次回以降は、HTTPの代わりにHTTPSを利用するように伝えるためのセキュリティ機能です。これを利用する事で、対象となるドメインへのアクセスはHTTPS通信となります。以下はnginxでの設定の例です。

add_header Strict-Transport-Security "max-age=31536000";

指定した期間(max-age)の間ブラウザはHTTPSでアクセスを行うため、HTTPへ切り戻しが必要が無いと判断できた時点で、HSTSを有効にするのが良いでしょう。

新しいmixed contentを生み出さないための社内への啓蒙活動

せっかく完全HTTPS化の対応を行っても、新たにmixed contentが生み出されてしまっては意味がありません。そこで、エンジニアやデザイナーなどコンテンツを作成するメンバーに向けて mixed contentを作らないためのポイントを伝え理解してもらう事が重要です。記事コンテンツ制作の過程でmixed contentの存在有無のチェックをオペレーションに導入してもらうなど、新たなコンテンツがHTTPS化の恩恵をきちんと受けることができるように対応しました。

Content-Security-Policy(CSP)レポートの活用

ページを一つ一つ目視で確認しmixed contentを発見することには限界があり、また定期的にページを巡回する作業は効率がよくありません。そこで、自動的にmixed contentを検知する仕組みを取り入れます。CSPは、特定の攻撃を検知し、影響を軽減するために追加できるレキュリティレイヤーです。Report-Onlyモードで動作させることで、クライアントのブラウザからmixed contentとなるJSON形式のレポートをreport-uriへ送信することができます。

以下はnginxのヘッダの設定例です。

add_header Content-Security-Policy-Report-Only "block-all-mixed-content; report-uri https://test.mwed.jp/csp-report;";

私たちは一部のユーザにCSPヘッダーを挿入しレポートを送信してもらっています。受信したJSONデータをElastic Searchにデータを投入しKibanaを用いて可視化しています。 https://report-uri.io/などの収集サービスもあるので自前で受信環境を用意する手間を省くことはできます。

以下の図は、受信したCSPレポートを可視化した例です。これからも、CSPレポートを活用しmixed contentsへの対応を日々続けて行き、サービスの品質向上を目指していきたいと思います。

最後に

既にアプリケーションで一部の通信をHTTPSで配信していたので、全ての通信を強制的にHTTPSに変更してしまえば動くのでは、と思い作業を進めていましたが、つまずきポイントは多く存在しました。何よりもHTTPS化の過程で、サービスへ関わる多くの方の協力があって達成できました。この場を借りて感謝をお伝えします。 サービスの完全HTTPS化はこれからの、まだHTTPSに踏み切れていない方!これを機会にHTTPS化を検討してみませんか??


みんなのウェディングはソフトウェアエンジニアを積極的に募集中です。興味のある方はWantedlyからご連絡よろしくお願いいたします。