From 6b34719397e4e3982697760c3df215563a9ef979 Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Sat, 26 Sep 2026 03:35:08 +0000 Subject: [PATCH] contact messages: inert .file attachment blobs, universal forced download MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework attachment storage and serving per the refined separation scheme: - Non-media uploads are stored as {hash}.file blobs (store_attachment) — the original extension never lands on the filesystem, so the store directory holds nothing double-click-executable. The original name lives only in the URL: /_f/{hash}/{original-name}. The .file suffix itself is rejected in URLs. - Serving is strictly separated: /_f/{name} serves media only (hash with or without extension, .orig. still blocked) and 404s .file names; /_f/{name}/{filename} serves only {name}.file blobs, never media, never by hash alone. - Every /_f/ response now carries bare 'content-disposition: attachment' (the URL's last segment already names the download) and x-content-type-options: nosniff — media included. Subresource fetches (,