げっとシステムログ

WEB開発メモ

npm reload で live reload しつつ CSP 対応する

「体系的に学ぶ 安全な Web アプリケーションの作り方」を読んで CSP ヘッダをちゃんと設定してみようという試み。

S3 + CloudFront でやってみたという話は次の記事で。

  • npm パッケージの reload を使用して live reload する
  • 必要な CSP ヘッダを整える
  • Mozilla Obsertatory で結果を確認する
CONTENTS
  1. reload-wrapper を使用して live reload する
  2. Strict-Security-Policy
  3. X-Content-Type-Options
  4. X-Frame-Options
  5. X-XSS-Protection
  6. Referrer-Policy
  7. Content-Security-Policy
  8. Mozilla の Obsertatory を使用して結果を確認する
  9. まとめ
  10. 参考資料

TOP

reload-wrapper を使用して live reload する

reload を使用して live reload する。 用意されているコマンドラインツールはヘッダーの指定ができないので、ラッパーを用意した。

$ npm install --save-dev reload-wrapper

package.json にスクリプトの設定を行う。

{
  "script": {
    "reload": "reload-wrapper -d ./public -w ./public/dist"
  }
}

headers.json にヘッダを指定する。

[
  ["Strict-Transport-Security", "max-age=31536000"],
  ["Content-Security-Policy", [
    "default-src 'self'",
    "object-src 'none'",
    "base-uri 'none'",
    "form-action 'self'",
    "connect-src 'self' https://api.example.com",
    "img-src 'self' https://www.google-analytics.com/",
    "font-src 'self' https://fonts.gstatic.com/ https://use.fontawesome.com/",
    "script-src 'self' https://www.google-analytics.com/ https://www.googletagmanager.com/",
    "style-src 'self' https://use.fontawesome.com/ https://css.getto.systems/"
  ]],
  ["X-Content-Type-Options", "nosniff"],
  ["X-Frame-Options", "DENY"],
  ["X-XSS-Protection", "1; mode=block"],
  ["Referrer-Policy", "same-origin"]
]

サーバーを起動する。

$ npm run reload

TOP

Strict-Security-Policy

指定した秒数の間、 https でアクセスするように指示するもの。

Strict-Transport-Security: max-age=31536000

max-age は 31536000(1年)にした。

TOP

X-Content-Type-Options

Content-Type を厳密に解釈するよう指示するもの。

X-Content-Type-Options: nosniff

TOP

X-Frame-Options

frame や iframe での読み込みを許可しないように指示するもの。

X-Frame-Options: DENY

TOP

X-XSS-Protection

XSS フィルタを強制的に有効にするもの。

X-XSS-Protection: 1; mode=block

TOP

Referrer-Policy

同じ origin のみに Referrer をつけるように指示するもの。

Referrer-Policy: same-origin

TOP

Content-Security-Policy

ページに含まれるコンテンツのうち、どのコンテンツを実行するかを指示するもの。 適当にやると JavaScript が全滅するので、エラーを見つつ調整する必要がある。

default-src

デフォルトではサイト内のコンテンツのみ許可する。

default-src 'self'

その他、個別に細かく調整する必要がある。

object-src

object タグなどは使用していないので許可しない。

object-src 'none'

base-uri

base タグは使用していないので許可しない。

base-uri 'none'

form-action

form の action は self のみ許可する。

form-action 'self'

connect-src

ページからアクセスする先を指定する。

connect-src 'self' https://api.example.com/

<a> ping、Fetch、XMLHttpRequest、WebSocket、EventSource の宛先になっているものを指定する。

img-src

画像の読み込み先を指定する。

img-src 'self' https://www.google-analytics.com/

google analytics は img タグを生成している。

font-src

フォントの読み込み先を指定する。

font-src 'self' https://fonts.gstatic.com/ https://use.fontawesome.com/

web フォント、font awesome はフォントを読み込んでいる。

script-src

スクリプトの読み込み先を指定する。

script-src 'self' https://www.google-analytics.com/ https://www.googletagmanager.com/

google analytics は googletagmanager にもアクセスしていた。

ページ内で使用するスクリプトは外部ファイルに切り出して読み込ませる必要がある。

style-src

スタイルの読み込み先を指定する。

style-src 'self' https://use.fontawesome.com/

font awesome はフォントを読み込んでいる。

ページ内で使用するスタイルは外部ファイルに切り出して読み込ませる必要がある。

全体

以上の内容をセミコロンで繋げて指定する。

Content-Security-Policy: default-src 'self'; object-src 'none'; connect-src 'self' https://api.example.com; img-src 'self' https://www.google-analytics.com/; font-src 'self' https://fonts.gstatic.com/ https://use.fontawesome.com/; script-src 'self' https://www.google-analytics.com/ https://www.googletagmanager.com/; style-src 'self' https://use.fontawesome.com/ https://css.getto.systems/

長い。

script と style について

このヘッダを指定すると、インライン実行ができなくなる。 アプリケーションの作り方によっては詰む。

TOP

Mozilla の Obsertatory を使用して結果を確認する

本番環境に適用した後、Obsertatory - Mozilla でスコアをチェックできる。 まだ必要なことがあれば対応していきたい。

TOP

まとめ

CSP ヘッダの調整を行なってみた。

スクリプトやスタイルの動かない部分がないか十分テストしてから本番環境に適用してスコアを良くしていきたい。

TOP

参考資料

TOP