要約
- RFC 1806 の
inlineとattachmentは次に望む扱いを示す値であり、表示、クリック、保存が完了したことを示す観測値ではなかった。 - multipart の外側と内側には別々の関門があり、
filenameも保存を選んだ場合の候補にすぎず、ローカルのパスや上書きを指示できなかった。 - 後続の RFC は日時、国際化された名前、HTTP 応答、フォーム送信へ用途を広げたが、遠隔の文字列とローカル効果を分離する原則は維持した。
MIME は材料を識別しても画面を決めなかった
RFC 1521 によって、インターネットメールはテキストだけでなく、画像、アプリケーションデータ、入れ子の multipart を運べるようになった。後の RFC 2045 と RFC 2046 は転送符号化とメディア型、複合構造の規則を整えた。受信プログラムは各部分の境界と、送信者が主張する種類を読めた。
それでも、読者にどう見せるかは決まらない。画像を文章の流れへ展開できる画面もあれば、項目名だけを並べる端末もある。安全に扱えないメディア型もある。内容の構造と受信環境の能力は、別の情報だった。
1995 年 6 月に Experimental として出た RFC 1806 は、任意の MIME エンティティに付けられる Content-Disposition を提案した。送信側は望ましい提示方法を表現できる。フィールドがなければ、メールユーザーエージェントは適切だと思う方法を自由に選ぶ。この自由は例外ではなく、受信側がもともと持つ権限の確認だった。
一つの値につき一つの次動作
inline は通常の表示の流れで自動的に提示する意図を表した。ただし、その部分を包む multipart の規則が優先する。attachment は提示の前に利用者の追加操作を求めた。グラフィカルなクライアントはアイコンを置けるし、文字端末は選択肢の一覧を作れる。規格は操作の境界を示し、見た目を固定しなかった。
ここで inline を「表示済み」と読むと、証拠の時間が逆転する。クライアントがメディア型を扱えない、危険だと判断する、読み込みに失敗する、といった経路は残る。attachment も、利用者が開いたことや保存したことを意味しない。フィールドは未来の扱いへの希望で、過去の効果の領収書ではない。
入れ子では関門が連続する。multipart エンティティ自体に disposition があれば、その値は容器全体に働く。外側が添付なら、まず外側を開く操作が要る。その後で初めて、内側の部分ごとの disposition が意味を持つ。外側の解析記録だけから、最奥の内容が人へ届いたとは言えない。
未知の disposition は attachment として扱う、と RFC 1806 は定めた。知らない新語に自動表示の権利を与えず、追加操作の側へ倒したのである。未知のパラメータは無視できた。意味を推測して効果を増やすのではなく、不確実性のまま露出を抑える設計だった。
保存名の前にはもう一つの関門があった
任意の filename パラメータは、利用者が部分を切り離して保存する場合の既定名を提案した。inline の部分にも付けられるため、名前が届いてもファイルが一度も作られないことがある。
受信側は値に含まれるディレクトリ情報を尊重せず、末尾の成分だけをローカル規則に合わせて扱う必要があった。また既存ファイルの上書きを避けなければならない。送信側には、受信機の区切り文字、予約名、書き込み可能な場所、既存名、拡張子とアプリケーションの結び付きが見えないからだ。
RFC 1806 の安全性の節は、失敗を抽象語で済ませなかった。起動時に読まれるファイルの作成、システムファイルや既存ファイルの置換、コマンド検索パスへの実行物の配置、パイプへの送出が挙げられている。名前や配置によって、利用者が明示的に始めていない解釈や実行を起こしてはならない。
したがって受信記録には段階が要る。生の文字列、パーサーが得たパラメータ、削除したパス要素、衝突回避後の実名、ファイルシステムの書き込み、後続アプリの起動はそれぞれ別の事実である。Content-Disposition だけで後半を証明することはできない。
標準化しても日時は証言のままだった
RFC 1806 の情報ページによれば、1997 年 8 月に RFC 2183 が Proposed Standard として置き換えた。改訂版は inline、attachment、受信側によるファイル名検査を継承し、作成日時、変更日時、参照日時、おおよそのサイズを追加した。
属性が増えると、転送された部分はファイル台帳のように見える。しかし RFC 2183 は、Unix と POSIX の st_ctime が作成時刻ではないと注意した。日時は送信者が運ぶ主張であり、受信側が保存するかを決める。概算サイズは空き容量の判断には使えても、正確なダイジェストでも、割り当て成功の保証でも、書き込み完了の証明でもない。
同 RFC は拡張値の登録手続きも整えた。現在の IANA Content Disposition レジストリには初期の値と、後の特定コンテキスト向けの値が並ぶ。登録は定義の所在を証明する。あるクライアントが実装したことや、異なるプロトコル位置で同じ意味になることまでは証明しない。
人が読む名前には ASCII の外側が必要だった
RFC 1806 自身、最初のパラメータ文法ではファイル名が US-ASCII に限られると認めていた。RFC 2231 は長い値を番号付きの断片へ分ける方法と、文字集合、任意の言語、パーセント符号化オクテットを含む拡張値を導入した。
これで多くの言語の名前を運べる一方、復元過程には新しい分岐が生じた。断片の欠落や順序、通常形と拡張形の混在、未知の文字集合、誤ったオクテットをどう扱ったかを残す必要がある。最終表示文字列は復号結果であり、生のフィールドそのものではない。
復号の正しさは安全性を保証しない。正確に復元されたパストラバーサルは依然としてパストラバーサルであり、読めるようになった予約名も予約名である。文字を表現できることと、その文字をローカル名として許可することは別の関門だ。
HTTP では普及が標準化より先に来た
RFC 2616 は 1999 年、Content-Disposition が HTTP 規格の一部ではないにもかかわらず、しばしば実装されていると記した。Web サーバーも、表現を通常表示から分けて保存させ、役立つ名前を提案したかった。
2011 年の RFC 6266 は HTTP 応答ヘッダーとしての利用を標準化した。ここでもファイル名は advisory、つまり助言にすぎない。ユーザーエージェントは許可されない場所をサーバーに選ばせず、最後以外のパス成分を捨て、危険な後続処理を招く拡張子を疑い、制御文字や特殊なファイル名を無害化しなければならない。
応答が互換用 filename と拡張 filename* の両方を含む場合、両者を理解する受信側は後者を優先する。RFC 8187 は HTTP の拡張パラメータを改訂し、UTF-8 対応を必須にした。二つの値が食い違う可能性がある以上、どちらを選び、どう復号したかも独立した記録になる。
フォーム送信では向きが反転した
Content-Disposition は multipart/form-data の各部分にも現れるが、RFC 6266 はこの本文内フィールドを対象外と明記する。RFC 7578 は各部分に form-data と name を必須とし、ファイル部分では意味のある名前があれば filename を付けるよう求めた。
この経路ではブラウザーが送信者となり、Web アプリケーションが自分のストレージを守る受信者になる。渡された名前を盲信せず、ローカル規則に合わせ、ディレクトリ情報を捨てる原則は同じである。一方、RFC 7578 はこの位置で filename* を使ってはならないとする。ダウンロード応答に正しい文法をアップロード本文へ持ち込めば、同名フィールドでも誤解釈になる。
メール、HTTP ダウンロード、フォームアップロードをつなぐものは、一つの万能文法ではない。遠隔側が希望と人間向けの名前を届け、ローカル側が表示、保存、実名、実行を決めるという権限の境界である。
出典
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
