静的サイトの画像管理をどこに置くか
記事に画像を貼れるようにしたときの設計メモです。
落とし穴: 生成物に直置きする
公開ディレクトリ(生成された静的HTMLの置き場)に画像をアップロードする方式は、一見素直ですが破綻します。公開のたびに生成物を掃除して作り直すため、置いた画像が消えるからです。
正本と生成物を分ける
そこで、画像も記事と同じく「正本」側に置くことにしました。
content/
posts/ ← 記事の正本(.md)
uploads/ ← 画像の正本
dist/ ← 生成物(毎回作り直される)
uploads/ ← 公開時に content/uploads/ からコピー
公開処理が content/uploads/ を dist/uploads/ へコピーします。これで「画像も記事と一緒にバックアップされる」「生成物はいつ消しても復元できる」という静的サイトの利点が画像にも及びます。
アップロード時の検査
管理画面からのアップロードは、拡張子の許可リストに加えてファイルの中身(マジックバイト)も確認しています。拡張子だけの検査は、PHPコードを .png と偽って置かれる古典的な攻撃に無力だからです。
- 許可: jpg / jpeg / png / gif / webp / svg
- ファイル名は記号を落として正規化し、衝突したら連番を付ける
小さな道具でも、ファイルを受け取る口だけは丁寧に作る価値があります。