multipart/form-data の Content-Type は大文字小文字を気にする必要があるか
AWS WAF の scope-down statement で Content-Type: multipart/form-data をマッチさせる際、text_transformation に LOWERCASE を使うべきか NONE のままでよいかを調査した。
結論
ブラウザからのファイルアップロードが対象であれば NONE(大文字小文字を区別する)で問題ない。
さらに、WAF の除外ルールとしては NONE の方がセキュリティ的に安全。
根拠
RFC 2045 §5.1 — 受信側のルール
content := "Content-Type" ":" type "/" subtype
*(";" parameter)
; Matching of media type and subtype
; is ALWAYS case-insensitive.RFC 2045 の case-insensitive 規定は受信者が寛容に扱うべきという意味であり、送信者が大文字で送ってよいという保証ではない。
HTML Living Standard — ブラウザの送信仕様
HTML Living Standard §4.10.22.3 (form submission algorithm) に以下の記述がある。
Let body be the result of running the multipart/form-data encoding algorithm with entry list and encoding.
Let mimeType be the isomorphic encoding of the concatenation of
"multipart/form-data; boundary="and the multipart/form-data boundary string generated by the multipart/form-data encoding algorithm.
"multipart/form-data; boundary=" が小文字のリテラル文字列として仕様に直書きされている。このアルゴリズムを実装するブラウザは必ず小文字で mimeType を構築する。
WHATWG(Apple・Google・Mozilla・Microsoft が参加する標準化団体)が管理するこの仕様に Chrome / Firefox / Safari は準拠しているため、主要ブラウザは必ず小文字で送信する。
また WHATWG MIME Sniffing Standard の「parse a MIME type」でも、ブラウザが MIME type を処理する際は ASCII lowercase に正規化すると規定されている。
まとめ
| クライアント | Content-Type の casing | 根拠 |
|---|---|---|
| ブラウザ(Chrome/Firefox/Safari) | 必ず小文字 | HTML Living Standard 仕様 |
| curl・カスタム HTTP ライブラリ等 | 大文字もあり得る | RFC 2045 が case-insensitive を規定 |
WAF 除外ルールとしての考え方
LOWERCASE を使うと大文字変種も除外してしまう。WAF の除外(スキップ)ルールでは除外範囲を狭くする方がセキュリティ的に優れる。
NONE(大文字小文字を区別): ブラウザ送信の小文字のみ除外。非ブラウザクライアントがMULTIPART/FORM-DATAと送ってきた場合は WAF が検査する → 安全LOWERCASE(大文字小文字を無視): あらゆる表記を除外。非ブラウザクライアントも除外されてしまう → やや広め
ブラウザ経由のファイルアップロードを対象とした除外ルールであれば、NONE が正しい選択。