Files
pad/internal
xarmian d048631abc fix(attachments): the blocklist judges the same filename the download header serves (BUG-2818) (#1445)
A stored attachment name had three readers that disagreed. The extension
blocklist looked up filepath.Ext of the name as stored; the
Content-Disposition sanitiser dropped control characters, '"' and '\'
before serving it. So "x.s<VT>vg" or `x.s"vg` passed the blocklist
(".s<VT>vg" is no known extension) and was downloaded as "x.svg". For SVG,
whose bytes sniff as allowed text/xml, the extension is the whole defence.

The fix makes them read one string:

- DroppedFilenameRune (internal/attachments) is the ONE character rule:
  Unicode control characters (C0, DEL, C1), '"' and '\'. The header
  sanitiser uses it instead of its own switch.
- NormalizeFilename runs at BOTH ingest doors before ValidateUpload: the
  upload handler, and bundle import, which stored the manifest's name
  verbatim with none of the upload door's rules. It keeps the upload
  door's leaf reduction and BUG-2803's fallback, drops the predicate's
  characters, and trims trailing dots and spaces (which a download save
  strips) unless that would leave nothing.
- ServedFilename covers legacy rows stored before this: a name whose
  normalised extension is blocked is served as stem + ".bin".

Normalise rather than refuse: the attack still ends in the ordinary 415
extension_blocked, because its normalised name carries the extension it
was hiding, while a benign name with a stray tab is stored without it.

Visible change: stored attachment names lose control characters, quotes
and trailing dots/spaces.

Claude-Session: https://claude.ai/code/session_01Vf8uZmYdsrQqJtbAmjUFSX
2026-09-22 20:54:46 -04:00
..
2026-03-26 01:52:36 +00:00