エッジケースのテストファイル — 破損・途中切れ・空・拡張子偽装

36 ファイル · 直接リンク · 広告なし · 用途自由

ZIP 爆弾なし実行ファイルなしマルウェア文字列なしSHA-256 公開安全に展開可能

このライブラリのほかのページは「正常な PNG がほしい」という要望に応えるものです。このページが扱うのはもっと難しい問いです:途中で切れている、空である、名前が間違っている、種類を偽っている、あるいは含むべきでないデータを含んでいる――そんなファイルを受け取ったとき、あなたのコードはどう動くでしょうか。本番環境に届くのはまさにそうしたアップロードですが、手作業で用意するのが面倒なため、ほとんどのテストスイートでは一度も試されていません。

ここにあるファイルはすべて安全です。ZIP 爆弾、パストラバーサルのエントリ、実行ファイル、マルウェアのテスト文字列は含まれておらず、最大のアーカイブでも展開後 1 MB 未満です。失敗の仕方は本物ですが、中身に危険はありません。各ファイルの SHA-256 を公開しているので、フィクスチャとして固定できます。

まずはこの 2 つから。 .jpg という名前の HTML ファイルで、画像アップロードがドメイン上の格納型クロスサイトスクリプティングにつながるかどうかがわかります。数式ペイロード入りの CSV で、エクスポートしたデータが同僚のスプレッドシートで有効な数式として開かれてしまうかどうかがわかります。実際のバグを見つけることが最も多いのはこの 2 つです。

空のファイルとほぼ空のファイル

0 バイトのアップロードは、最も見落とされやすいケースです。最大サイズをチェックするバリデーターは最小サイズを忘れがちで、長さを確認する前に先頭バイトを読むコードは、きちんとエラーを返さずにここでクラッシュします。

ファイルテスト内容サイズ入手
zero-byte.txt完全に空のファイルです。最小サイズの検証、長さでの除算、そして先頭バイトがあるか確認する前に読み込むコードをテストします。0 Bダウンロード
one-byte.txt1 文字だけのファイルです。どの形式でも有効なヘッダーを持てないほど小さいため、種類の判定がきちんと失敗できるかを確認できます。1 Bダウンロード
empty-archive.zipエントリが 1 つもない、構造上は有効な ZIP です。展開は例外を投げずに成功し、何も出力しないのが正しい動作です。22 Bダウンロード

途中で切れたファイルと破損ファイル

ヘッダーは有効でも、データが不完全だったり壊れていたりするファイルです。中断されたアップロードは実際にこうなります。ヘッダーを信用して残りをストリーム処理するコードはここで失敗し、どこで失敗するかを見れば、エラー処理が想定どおりの場所にあるかどうかがわかります。

ファイルテスト内容サイズ入手
truncated.png有効な PNG シグネチャと IHDR を持ち、画像データの途中で切れています。デコーダーは部分的な画像を返すのではなく、ここでエラーを出します。4 KBダウンロード
corrupt-crc.png長さも構造も正しいものの、画像データ内の 1 バイトが反転しており、保存された CRC と一致しません。厳密なデコーダーは拒否し、寛容なデコーダーは誤ったピクセルを返します。9 KBダウンロード
truncated.jpg60% で途切れた、画像終了マーカーのない JPEG です。多くのデコーダーは失敗せずに途中までデコードした画像を返すので、自分のデコーダーがどう動くか知っておく価値があります。603 Bダウンロード
truncated.zipセントラルディレクトリが途切れています。アーカイブのアップロードが途中で止まるとこうなります。実際に最もよく見かける破損 ZIP です。3 KBダウンロード
malformed.json末尾のカンマ、引用符のないキー、閉じていない波かっこを含みます。パーサーが汎用的な失敗ではなく、役に立つ位置を報告するかをテストします。136 Bダウンロード

種類を偽るファイル

拡張子とバイト列の中身が食い違っています。アップロード処理が拡張子やブラウザから送られる Content-Type を信用していると、これらは素通りします。重要なのは .jpg という名前の HTML ファイルです。画像の Content-Type で返すなら無害ですが、自分のドメインから HTML として配信すれば格納型クロスサイトスクリプティングになります。

ファイルテスト内容サイズ入手
actually-a-png.jpg拡張子が .jpg の本物の PNG です。拡張子で処理を振り分けるものは、これを誤ったデコーダーに渡してしまいます。9 KBダウンロード
actually-html.jpg拡張子が .jpg の HTML 文書です。アプリケーションがこれを保存し、推測した Content-Type で返すと、格納型クロスサイトスクリプティングになります。335 Bダウンロード

メタデータとプライバシー

スマートフォンで撮ったままの写真には、撮影場所と画像の向きが記録されています。前者を削除しなければユーザーの位置情報が漏れ、後者を無視すれば縦向きの写真がすべて横倒しで表示されます。このファイルには両方が含まれているので、パイプラインがそれぞれを正しく処理するかを確認できます。

ファイルテスト内容サイズ入手
exif-gps-orientation.jpgGPS 座標(トロントの CN タワー)と、正しく表示するには時計回りに 90 度回転させることを意味する Orientation 6 を持っています。位置情報を削除しているか、回転を反映しているかの両方の確認に使ってください。1 KBダウンロード

テキスト、文字コード、改行コード

最初の列に見える文字として現れてしまうバイトオーダーマーク、カンマや改行そのものを含む引用符付きフィールド、1 つのファイルに混在する 3 種類の改行コード、そして末尾に改行のないファイル。どれも実際のユーザーが送ってくるファイルではごく普通のことです。

ファイルテスト内容サイズ入手
bom-crlf-quoted.csvUTF-8 のバイトオーダーマーク、CRLF の改行、カンマを含む引用符付きフィールド、エスケープした二重引用符、フィールド内の改行そのもの、ASCII 以外の名前を含みます。最初の列見出しに BOM が表示されたら、それがバグです。180 Bダウンロード
unicode-torture.txt結合文字、ゼロ幅スペース、右から左への上書き、アストラル面の文字、6 つのコードポイントからなる国旗の絵文字を含みます。長さの数え方、切り詰め、正規化をテストします。565 Bダウンロード
mixed-line-endings.txt1 つのファイルに LF、CRLF、単独の CR が混在し、最終行には改行がありません。行数を数えるコードは、ここでしばしば自分自身と矛盾した結果を出します。107 Bダウンロード
no-trailing-newline.txt改行なしで終わるファイルです。確認せずに追記すると、2 つのレコードが 1 つにつながってしまいます。48 Bダウンロード

扱いにくいファイル名

テストするのは中身ではなく名前です。長い名前はデータベースの列やファイルシステムの上限を超え、ASCII 以外の文字を含む名前は Content-Disposition ヘッダー、URL エスケープ、そして macOS での Unicode の合成形と分解形の違いで問題を起こします。

ファイルテスト内容サイズ入手
文件名-with spaces-🌲.txtファイル名に漢字、スペース、絵文字を含みます。Content-Disposition のエンコード、URL エスケープ、macOS の Unicode 分解形の正規化をテストします。194 Bダウンロード

構造とリソースの上限

壊れているのではなく、扱いにくいだけの有効なファイルです。1 万個のエントリを持つアーカイブ、多くのパーサーの既定値より深くネストした JSON、暗号化されたアーカイブがあります。どれも攻撃ではありませんが、素朴な実装では何かしらのリソースを使い果たしてしまう形です。

ファイルテスト内容サイズ入手
many-entries-10000.zip1 万個の小さなエントリで、展開後の合計は 1 MB 未満です。セントラルディレクトリの解析とエントリごとのオーバーヘッドをテストします。意図的に ZIP 爆弾にはしていません。1.6 MBダウンロード
deeply-nested.json512 階層のネストです。有効な JSON ですが、多くのパーサーの既定の上限より深く、再帰的なパーサーのスタックを使い果たすほどの深さです。3 KBダウンロード
encrypted-password-test.zipZipCrypto で暗号化されており、パスワードは test です。パスワードなしの展開は、意味不明なデータを出力せずにきちんと失敗する必要があります。292 Bダウンロード

スプレッドシートの数式インジェクション

=、+、-、@ で始まる CSV のセルは、Excel、Google スプレッドシート、LibreOffice で開くと数式として解釈されます。アプリケーションがユーザー入力のテキストを、これらの先頭文字をエスケープせずに CSV に書き出していると、その入力を実行可能な数式として配布していることになります。ここにあるペイロードは無害な計算をするだけです。

ファイルテスト内容サイズ入手
formula-injection.csv表計算アプリが数式として扱う =、+、-、@ で始まるセルを含みます。ペイロードは無害な計算を行うもので、1 つはこのサイトへのリンクを作ります。コマンドを実行するものはありません。189 Bダウンロード

3D モデル:空のメッシュ、壊れたメッシュ、紛らわしいメッシュ

メッシュを扱うコードは、閉じていて、サイズが妥当で、面の向きが正しく、三角形が 1 つ以上あるモデルを前提にしがちです。しかしユーザーはそれ以外のあらゆるものをアップロードします。ここでは、空のメッシュ、面積 0 の三角形と裏返った三角形、非多様体メッシュ、float32 でうまく扱えないほど大きい・小さい座標、アップロード途中で切れた GLB、ヘッダーが嘘をつく STL、STL のふりをした GLB、そして「solid で始まれば ASCII」という定番のチェックに引っかかるバイナリ STL を収録しています。これらは 3D フォルダーにあり、正常な 3D サンプルは 3D モデルのカテゴリにあります。

ファイルテスト内容サイズ入手
empty-mesh-zero-triangles.stl構造上は有効なバイナリ STL で、80 バイトのヘッダーと 0 という三角形数だけを含みます(84 バイト)。バウンディングボックス、中央寄せ、サムネイルのコードは、ここでゼロ除算や空の配列へのアクセスを起こしがちです。84 Bダウンロード
empty-scene-no-meshes.glbシーンと空のノードが 1 つずつあるものの、メッシュ、バッファ、マテリアルを持たない有効な glTF 2.0 バイナリです。Khronos のバリデーターに合格します。ビューアーは例外を投げずに空のシーンを表示すべきです。276 Bダウンロード
degenerate-triangles.stl10 mm の立方体に、面積ゼロの三角形を 6 つ加えたものです(重複した頂点、同一直線上の点、イプシロン未満の細長い三角形)。法線の計算でここで長さゼロによる除算が起き、NaN の法線はここから生まれます。984 Bダウンロード
flipped-normals-inside-out.stlすべての三角形が時計回りで、保存された法線が内側を向いている 10 mm の立方体です。背面カリングがあると真っ黒か見えない状態で描画され、符号付き体積は負になります。684 Bダウンロード
non-manifold-open-box-and-fins.stl上面のない箱(開いた境界)に、それぞれ 1 本の辺を他の 2 つの面と共有するフィンを 2 枚加えたものです。このままでは印刷できず、スライサーや修復ツールは両方の問題を指摘すべきです。684 Bダウンロード
huge-coordinates-1e7.stl原点から 1,000 万単位離れた位置を中心とする 100 単位の立方体です。この大きさでは float32 は整数しか表せないため、精度、カメラのファープレーン、自動フレーミングの問題がすべて現れます。684 Bダウンロード
tiny-scale-1e-6.stl差し渡し 100 万分の 1 単位の立方体です。ミリメートルとして読むと 1 マイクロメートルで、最小サイズのチェック、単位の推測、頂点の結合に使うイプシロンをテストします。684 Bダウンロード
extreme-float-values.stl頂点座標が float32 の最大値に近い ±3.0e38 で、非正規化数 1e-40 の値でできた三角形を含みます。ファイルに NaN や Infinity はありませんが、float32 でバウンディングボックスのサイズを計算すると Infinity にオーバーフローします。234 Bダウンロード
truncated.glb有効なテクスチャ付き GLB の先頭 60% です。ヘッダーは完全な長さを主張したままで、BIN チャンクが途中で終わっています。GLB のアップロードが中断されるとこうなります。80 KBダウンロード
wrong-triangle-count-header.stluint32 の三角形数が 1,000 となっているのに、実際には 12 個しかないバイナリ STL です。数を信用するリーダーはファイルの終わりを越えて読み、厳密なリーダーは 84 + 50 × 1,000 がファイルサイズと一致しないためファイルを拒否します。684 Bダウンロード
actually-a-glb.stl本物の有効な GLB(先頭のバイトは glTF)を、拡張子 .stl で保存したものです。拡張子で処理を振り分けるものは、これを STL パーサーに渡してしまいます。21 KBダウンロード
binary-stl-header-starts-with-solid.stl自由記述のヘッダーが solid という単語で始まる有効なバイナリ STL で、実際にいくつかのエクスポーターがこう書き出します。この接頭辞で ASCII STL を判定すると、このファイルは誤ったパーサーに送られます。代わりにファイルサイズと三角形数を比較しましょう。684 Bダウンロード
obj-missing-mtl.objmtllib の行が存在しないマテリアルファイルを指していること以外は有効な OBJ です。失敗するのではなく、ジオメトリは既定のマテリアルと警告付きで読み込まれるべきです。914 Bダウンロード
obj-negative-indices.obj面に、形式上許されている負の相対インデックス(f -3 -2 -1)を使う有効な OBJ です。手書きのパーサーの多くは正のインデックスにしか対応していません。675 Bダウンロード
立方体 cube-modèle-🧊.stlファイル名に漢字、アクセント付き文字、スペース、絵文字が混在する、有効な 10 mm の立方体です。モデルのアップロードにおける Content-Disposition、URL エンコード、ストレージのキーをテストします。684 Bダウンロード

アップロード処理の簡単なチェックリスト

  1. 最大サイズだけでなく最小サイズも確認する。0 バイトのアップロードは最も見落とされやすいケースです。
  2. ファイルの種類は、拡張子やブラウザが送る Content-Type ではなく、必ずバイト列から判定する。どちらも攻撃者が自由に操作できます。
  3. ユーザーがアップロードしたファイルは別ドメインから配信するか、Content-Disposition: attachment と X-Content-Type-Options: nosniff を付けて配信する。そうすれば、中身が HTML だったファイルが自分のオリジンで実行されることはありません。
  4. 画像を公開する前に EXIF を削除する。削除する前に Orientation タグを反映させておく。
  5. ユーザーの入力テキストを CSV に書き出すときは、先頭の =、+、-、@ をエスケープする。
  6. アーカイブのエントリ数、展開後の合計サイズ、パーサーの再帰の深さに明示的な上限を設け、上限に達したらわかりやすいエラーを返す。
  7. 途中までしかアップロードされなかったファイルをどう扱うかを決め、思い込みに頼らずここにある途中切れのファイルでテストする。

よくある質問

これらのファイルは危険ではありませんか?

危険ではありません。ZIP 爆弾、パストラバーサルのエントリ、実行ファイル、マクロ、マルウェアのテスト文字列は含まれていません。最大のファイルでも展開後 1 MB 未満です。失敗の仕方は本物(途中で切れた画像は実際に切れています)ですが、開いたマシンを攻撃するものは何もありません。スプレッドシートの数式ペイロードも、コマンドを実行するのではなく無害な計算をするだけです。

拡張子が .jpg の HTML ファイルは何のためのものですか?

このパックの中で最も価値のあるファイルです。アプリケーションがこれを画像として受け付けて保存し、後で中身から推測した Content-Type で配信すると、ブラウザはそれをあなたのドメイン上のページとして表示します。つまり、画像アップロード経由の格納型クロスサイトスクリプティングです。ファイルを受け付けること自体は問題ありませんが、HTML として配信し返すのは問題です。

CSV に等号で始まるセルがあるのはなぜですか?

Excel、Google スプレッドシート、LibreOffice は、=、+、-、@ で始まるセルを数式として解釈するからです。アプリケーションがユーザーの入力したテキストを、これらの先頭文字をエスケープせずに CSV に書き出すと、ユーザーがフォームに入力した内容が同僚のスプレッドシートで有効な数式として開かれてしまいます。対策は、書き出し時にそうしたセルの先頭にアポストロフィを付けるか、引用符で囲むことです。

写真には本当に GPS 座標が入っていますか?

はい。トロントの CN タワー(北緯 43.6426 度、西経 79.3871 度)の座標と高度が入っています。さらに Orientation 6 も設定されており、ビューアーは正しい向きで表示するために時計回りに 90 度回転させる必要があります。この 2 つで、あらゆる画像処理パイプラインが正しく扱うべき 2 点――公開前に位置情報を削除すること、縦向きの写真が横倒しにならないよう回転情報を反映すること――を確認できます。

自動テストスイートで使えますか?

はい、まさにそのためのファイルです。どのファイルも内容が固定されており、SHA-256 をここで公開しています。直リンクには長いキャッシュ有効期間と CORS を許可するヘッダーが付いています。テストでハッシュを固定しておけば、フィクスチャが変わったときにすぐ気づけます。

不具合や改善できそうな点を見つけましたか?いただいたメッセージはすべて読み、すぐに対応します。

正常なファイルが必要ですか?

ほとんどのテストで必要なのは正常に使えるファイルです。そちらも公開しています。本物の画像、動画、音声、文書、アーカイブ、データ、フォント、3D モデルを、正確なサイズとハッシュ付きで用意しています。