File attachments

Whistleblowers can attach evidence to a report. Files are stored with it, in PostgreSQL or in S3.

Limits and allowed types

Size 10 MB per attachment, before and after cleaning
GIF size 50 megapixels, all frames together
Number 5 per report
Allowed PDF, JPEG, PNG, GIF, WebP, TXT, CSV, DOCX, XLSX, checked by both MIME type and file extension
Refused SVG, executables, archives and every other type. Legacy .doc/.xls too: their author cannot be removed, so save them as .docx/.xlsx and attach again

Access control

  • Whistleblower: /status/attachments/{id}, with an ow-status-session cookie tied to the report that owns the file. No other report's files are reachable. The session ends 2 hours after login and viewing does not extend it, so its remaining lifetime does not tell when the case was last opened.
  • Admin: /admin/reports/{report_id}/attachments/{id}, with an admin session; the file must belong to that report.

Every download carries Content-Disposition: attachment, so the browser never renders a file inline: no MIME sniffing, no script injection.

Privacy and deletion

  • Metadata removed on upload:
    • JPEG, PNG, WebP and GIF, also photos inside DOCX/XLSX: EXIF/GPS, camera data, XMP, ICC profiles and text chunks. Only the orientation tag stays.
    • JPEG, PNG and WebP are not re-encoded: pixels, colours and animation frames stay exactly as uploaded. Data after a JPEG's end (a motion-photo video) is removed.
    • PDF: document info, XMP on the document, its pages and images, comment authors and times, the EXIF of embedded JPEG photos, the file identifier. A PDF with files embedded in it is refused.
    • DOCX/XLSX: author, company and custom properties, SharePoint columns, the folder a workbook was saved in, the account name in template and link paths, revision-session ids and document variables.
    • A file that cannot be parsed for cleaning is refused. Plain text is stored as uploaded.
  • Office authors anonymised: comment and tracked-change authors, initials and account ids in DOCX/XLSX become Author. Embedded thumbnails, zip timestamps and zip extra fields are removed. A comment's text is content and stays, and Excel writes the author's name into it.
  • Filenames encrypted with the report's data key (older names by migration 003). S3 object keys are random ids, never the filename; objects stored before v1.5.0 keep their old key.
  • Encrypted at rest: file bytes are encrypted with the report's data key before they reach PostgreSQL or the S3 bucket. Attachments uploaded before v1.4.0 stay unencrypted and readable.
  • Deletion: a hard-deleted report (DSGVO Art. 17) loses its attachment rows by CASCADE DELETE, and its S3 objects are deleted too.

Edit this page on GitHub