Commit Graph

3 Commits

Author SHA1 Message Date
41a03b9987 fix(14.2): WR-03 uploads route sandboxes files and downloads non-images
The route answered with the blob's stored Content-Type, which attach.Store
sniffs from the bytes, so a public text upload starting with <html> was
served as text/html on the application origin; nosniff does not help when
the declared type is already HTML. Every response now carries a sandboxing
Content-Security-Policy, and a successful response whose type is not a
raster image (JPEG, PNG, GIF, WebP, AVIF) gets Content-Disposition:
attachment, on GET and HEAD. Covers stay inline.
2026-10-12 11:20:43 +02:00
2c5c0583f2 test(14.2-04): uploads mount and access log unit tests; the uploads route owns its prefix
- TestUploadsMount: key off registers nothing; on, a public blob is served
  with its content type and nosniff, HEAD has no body, private, missing,
  partition and encoded traversal paths 404, an unpublished bucket or
  database 404s, a custom prefix is honoured
- mountUploads refuses a plugin route at or under the prefix, so
  BuildRouter fails instead of only an identical pattern failing at
  Assemble (README and storage docs updated)
- TestAccessLog: pattern and status for 200, handler 404 and recovered
  panic, path only for unmatched requests, locale-prefixed requests keep
  the pattern, integer duration_ms, no query, header or Authorization
  value, ResponseController flush still works
2026-10-11 23:23:38 +02:00
0b6d757b40 feat(14.2-01): opt-in storage.uploads.serve route for public uploads
- surf mounts GET {storage.uploads.public_path_prefix}/{path...} on
  attach.StaticHandlerPublic when storage.uploads.serve is true
- bucket and database resolved per request; X-Content-Type-Options: nosniff
- surf README, storage and configuration docs describe the key
2026-10-11 17:36:54 +02:00