Fragments of verbose memory

冗長な記憶の断片 - Web技術のメモをほぼ毎日更新

Feb 13, 2021 - 日記

CORSセーフリストリクエストヘッダーに関するトリビア

セキュリティに特別な配慮が必要なサーバーサイドアプリケーションは、ブラウザに対してCORS の一部としてAccess-Control-Allow-Headersというアドバイスをします。これは、サーバーサイドでクロスオリジンサイトとして安全とアドバイスしたサイトに対し「但し、Access-Control-Allow-Headersにあるヘッダーに限る」と制限をつけるものです。しかしながらヘッダーの性質上セキュリティに問題なりにくいヘッダについてはわざわざここにリストされていなくてもOKという取り決めがあります。これがCORSセーフリストリクエストヘッダー となります。

セーフリストリクエストヘッダーには以下の5つが決められています。どれもおなじみのものですね。

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type
  • Range

従って、通常これらのヘッダーがAccess-Control-Allow-Headersにリストされる必要はありませんが、ややこしい事にこれらをAccess-Control-Allow-Headersに追加されることで、追加制約が解除される という仕様があります。

  • Accept-LanguageとContent-Language: 0-9, A-Z, a-z, スペースまたは*,-.が利用可能になる。
  • Accept と Content-Type: CORS-unsafeのリクエストヘッダバイト: 0x00-0x1F (許可されている 0x09 (HT) を除く)、"():<>?@[\]{}、および 0x7F (DEL)利用可能になる。
  • Content-Typeの場合: application/x-www-form-urlencoded、multipart/form-data、text/plainのいずれかのMIMEタイプが利用可能になる。
  • すべて:値の長さを128以上にすることができる。

覚えておいてもあまり使わなそうですね。ただ他人が書いたコードを読んでいてAccess-Control-Allow-Headersにセーフリクエストヘッダーが入っているのを発見して安易に削除すると挙動が変わってしまうことがあるので注意しましょう。

ワイルドカードによる指定

Access-Control-Allow-HeadersAccess-Control-Allow-Headers: *のように、ワイルドカードによる指定が可能です。ただ一つ注意があってAuthorizationヘッダはワイルドカードに含まれません。*を使いたいけどさすがにAuthorizationを他サイトに送って欲しくないと言う心配は不要です。むしろ認証トークンの送信にAuthorization以外のカスタムHTTPヘッダーを利用するのは止めた方がいいと言うことですね。

まとめ

CORSセーフリストリクエストヘッダーは、通常の利用では意識する必要はありませんが、特殊な制約を解除したい場合にAccess-Control-Allow-Headersへ明示的に追加することで対応可能です。特に他人のコードをメンテナンスする際は、一見不要に見えるセーフリストヘッダーの記載が実は重要な役割を果たしている可能性があることを覚えておきましょう。

参考リンク