HSTSに関して、話題に上がったことがあったので、改めてHSTSは何なのかをまとめてみました。

TL; DR

  • HTTPSを強制するもの
  • TLDベースとレスポンスヘッダーベースがある
  • 導入するときは気をつけないといけない

HSTSの導入モチベーション

HTTPSが有効ではないと、中間者攻撃をされる危険性があることは承知の上で議論を進めていきます。 わからない方はhttps httpとかでググってみよう

ただ、例えばHTTPでアクセスしたあとにHTTPSにリダイレクトするようなサイトを構築している場合、最初のアクセスのタイミングで中間者攻撃されるような危険性のある環境でクライアントが接続しに来ると、いくらHTTPSで疎通していたとしても攻撃される危険性が残ってしまいます。

機微なCookieに対してSecure属性をつけるなど他での対策はできますが、当然それだけでは不足です。

ここで、「初回アクセス時からHTTPSを強制する」事ができれば、上記のような危険性を排除できます。これがHSTSが達成したいモチベーションです

HSTSするには

TLDベースで対処する

.dev.app など、比較的最近発行されたTLDではHTTPSを強制することが標準で備わっていることがあります。こういったドメインを用いればHSTSは強制的に有効になります。

レスポンスヘッダーで対処する

とはいえ大抵のアプリケーションは .com だったり .co.jp だったりを使っていると思います。こういったドメインはHSTSを強制する力はないため、独自で設定する必要があります。 「初回リクエスト時にHTTPSで接続する」ということがブラウザに知られている必要があるため、レスポンスヘッダーを用いて「このウェブサイトはHSTSだよ」ということを事前に伝えて置く必要があります。

そこで用いられるヘッダーが Strict-Transport-Security ヘッダーです。

使い方

このヘッダーには3つのディレクティブがあります。

ディレクティブ説明
max-ageブラウザが記憶する、HTTPSに強制する時間(秒)
includeSubDomains当該ドメインだけではなく、サブドメインもすべて対象にする(省略した場合は当該ドメインだけ)
preloadpreload対象に入れる(後述)

このディレクティブを適切に設定し、任意のリクエストのレスポンスヘッダーに追加するだけで、「次からの接続は」HTTPSが強制されるようになります

注意点

ここで大事なのはmax ageとincludeSubDomainsです。 max ageがながければ長いほど当然セキュアではあるのですが、その間証明書が失効するなどHTTPSで接続できない時間があると、ブラウザはそのウェブサイトへ接続できなくなってしまいます。 またincludeSubDomainが設定されればサブドメインにもその効果が波及されます。一つのドメインを踏むだけで、他のサブドメインに対しても効果が波及するのでよりセキュアではありますが、サブドメインがHTTPのみしか許可できない場合は、当然そこには接続できません。

例えば簡易的に CNAME などで外部サービスにサブドメインを発行しているケースだと、Let’s EncryptなどでHTTPS化していないケースが有り、そういったサービスを使う場合はHTTPS化されません。 そのようなドメインは局所的にしか使わないものかもしれませんが、一度includeSubDomain下に入ってしまえばそのドメインも対象になってしまうので、その外部サービスが使えなくなってしまいます。

またこれはmax-ageが消えるまで有効です。つまり初期のタイミングでは特にそのようなサービスと提携しておらず、問題なく接続できたとしても、後日そのようなサービスと連携する際に障害になるといったケースも発生しえます。

また、レスポンスヘッダーに付与されるという特性上、ブラウザにとっての初回アクセス時はどうしてもHTTP接続になるケースが発生しえます。これを防ぐ仕組みとしてpreloadというものが提供されています。

preload

preloadは仕様書では定義されていないものですが、Googleによって提供され、昨今の主要なブラウザには搭載されている機能となっています。 サポートしているブラウザはこちら

preloadをつけることによって、「そのブラウザ」ではなく「全ブラウザ」に対してHTTPS強制することが伝わります。 つまり誰かが生贄になってそのサイトに接続したあとは(タイムラグはありますが)それ以降そのサイトに訪れる人は全員HTTPSが矯正されるということです。

タイムラグを極力減らしたい方は https://hstspreload.org にて対象ドメインを設定することでその速度を早めることができます。

当初達成したかった目的はこのpreloadを使うことによって達成しうるのですが、当然上記で上げた注意点を考慮する必要があります。

preloadの設定ができるということは当然削除もできます

https://hstspreload.org/removal/

にて削除リクエストを送ることができますが、このリクエストが処理されるのはChromeユーザで6~12週間、他のブラウザはそれ以上の時間がかかるので、より一層設定には注意を払う必要があります。

無効化

Strict-Transport-Security: max-age=0 を設定することによって無効化できます。

まとめ

HTTPSが当たり前になってきている中で、HSTSの対応が求められるケースは増えて生きているかと思います。 上記注意点を考慮し、設定していきましょう。