LoginSignup
1
1

More than 3 years have passed since last update.

HSTSを導入することになった時のメモ書き

Last updated at Posted at 2021-02-17

初めに

恥ずかしながら少し前までHSTSの存在自体知らなかったのですが、
最近セキュリティ診断を実施した際に指摘を受けることが増えました。

社内の他の人が担当の環境で導入することになり
その方がうまくいかないとハマってたのでその時のアドバイスのメモ書きになります。
(存在すら知らなかった自分になぜ質問が来るのか...)

今後ハマってる人から別の質問が来たら追記するかもしれません。

なおQAは大概RFC6797を読むと解決しました。
今回は基本的に上記RFCの話を正として記載しますが実際の実装は各ブラウザによるためご注意ください。

HSTSって何

サーバ側ではなくクライアント側でHTTPからHTTPSに転送する仕組み(かなり意訳)

導入すると何がいいの

中間者攻撃のを受ける余地が減ります。

よくあるサーバ側でのHTTPSリダイレクトはHTTPSに転送する前に、
暗号化されていないHTTPで通信するためその際に通信を改竄される危険性が高まります。

例えばApacheで以下のような転送設定が行われているサイトがあったとします。
(このサイトではHSTSの設定を行なっていない)

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

このサイトにHTTPをアクセスを行なった場合Locationヘッダーに対してHTTPSのURLが格納されて応答されますが、
暗号化されていないため中間者攻撃等でLocationヘッダーが改竄され意図しないサイトへ転送される危険性が高くなります。

$ curl -I https://example.com
HTTP/1.1 301 Moved Permanently
(略)
Location: https://example.com/

つまり以下の2~3のタイミングで改竄される可能性が高まります。

  1. クライアントはhttp://example.comへのリンクを踏む
  2. クライアントがhttp://example.com/に要求を行う(暗号化されていない通信が発生)
  3. サーバがhttps://example.com/への転送を含む応答を返す(暗号化されていない通信が発生)
  4. クライアントはLocastionヘッダーのhttps://example.comにアクセスする(暗号化されている)

HSTSによる転送が有効な状態ではざっくり以下のようになります。
外部との通信に暗号化されていない通信が発生しないのでその分中間者に改竄される可能性が低くなります。

  1. クライアントはhttp://example.comへのリンクを踏む
  2. クライアントのブラウザ内でhttps://example.comへ転送する(具体的な処理未確認のため注意)
  3. クライアントはLocastionヘッダーのhttps://example.comにアクセスする(暗号化されている)

Chromeで確認してもらった限り2.の処理として307リダイレクトが発生しています。

設定

Strict-Transport-Securityヘッダーを設定するだけで良さそうです。

このヘッダーをブラウザが認識して初めてHSTSが有効になるので、
初回のアクセス時(ヘッダーを読んでいない時は)設定の有無に関わらず従来の前述のLocationヘッダーによる転送が発生します。

これに関してはHSTS preloadという機能で回避できるようです。
これはクライアント側に事前に設定されたリストのドメインは上記のヘッダーを認識していない状態でも
各ブラウザが指定されているリストからアクセス先のドメインが存在するかを探し、
HSTSによるHTTPS転送が行われのちアクセスするようです。
リスト入りを希望するのであればStrict-Transport-Securityヘッダーにpreloadパラメータを設定する必要があるようです。

拡張仕様か何かと思ったら同RFC内の12章に定義がありました。
なお This section is non-normative. が見えたのでブラウザの対応がどうか次第...
と書こうと思ったんですが
ここ曰く大概の最新のブラウザは対応しているらしいです。

ヘッダー設定した見たけどうまくいかない...

自分が実装する前に別の環境でやってる人が設定したのに301の転送(Apacheの設定)になるんだが...ってハマってたので。

ポートの設定は問題ないか

これは結局今回の問題になかったので実際の挙動は未確認ですが、
RFC6797内8.3において以下の記載があります

if the URI contains an explicit port component of "80", then the UA MUST convert the port component to be "443", or if the URI contains an explicit port component that is not equal to "80", the port component value MUST be preserved; otherwise, f the URI does not contain an explicit port component, the UA MUST NOT add one.

要は明示的にポートが指定されている場合かつポート80の場合は443に変換するけど、
それ以外の場合は保持してね!感じらしいです。

この部分のすぐ後ろの中役にも明示的にこれ以外のポートが指定されている場合は失敗するよって書いてあります。
なのでローカル環境などで8080等指定している環境はどうするんでしょう。
今回hostsファイルを設定した上でApacheのVirtualHostを設定して複数環境をポート80/443で持っていたので影響はありませんでした。

自己証明書を利用していないか

RFC6797の11.3に以下の記載があります。
今回知り合いはこれが原因で失敗していました。

If all four of the following conditions are true...
o a web site/organization/enterprise is generating its own secure
transport public-key certificates for web sites, and

o that organization's root certification authority (CA) certificate
is not typically embedded by default in browser and/or operating
system CA certificate stores, and

o HSTS Policy is enabled on a host identifying itself using a
certificate signed by the organization's CA (i.e., a "self-signed
certificate"), and

o this certificate does not match a usable TLS certificate
association (as defined by Section 4 of the TLSA protocol
specification [RFC6698]),
...then secure connections to that site will fail, per the HSTS design. This is to protect against various active attacks, as discussed above.

ざっくりかなり意味合いを省いて言えば自己証明書とか企業で独自で発行したやつ(多分PrivateCAとかの)証明書使ってるサイトは、
安全性のためにHSTSができないよ!って感じです。

ただし上記の部分の少し後ろにも書いてある通りそのCAをブラウザとかに登録すればいけるよってやつなので、
自己証明書を発行したときに使ったルート証明書をブラウザに登録するとか、
もしくは何かの環境で使ってるしっかりした証明書を持ってきてhostsファイル割り当ててやるとかで確認できるかと思います。

終わりに

知らない側からすればHTTPSに転送しているから大丈夫!みたいになることも多いですが
Web上でもあるURL入れたらフリーでセキュリティ診断できるようなサービスでも指摘されることが多い印象です。
設定自体はヘッダーのみですので影響等をみて問題なければ導入するのが良いでしょう。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1