Files
itworx-knowledge-hub-Public/docs/13-attachments.md
T

4.2 KiB

Attachments

Goals

  • Preserve school and project files.
  • Avoid filename/path vulnerabilities.
  • Deduplicate identical content.
  • Maintain authorization and provenance.
  • Detect corruption.
  • Never execute uploaded content.

Storage model

Physical blobs are addressed by lowercase SHA-256:

/var/lib/knowledge-hub/attachments/ab/cd/<full-sha256>

The physical path never contains the user's filename. A logical attachment reference stores the original display filename and metadata in PostgreSQL.

Temporary uploads use a separate same-filesystem quarantine directory so a validated file can be atomically moved.

Upload pipeline

  1. Authenticate and authorize.
  2. Enforce request and streaming limits.
  3. Sanitize display filename; reject path separators/control characters.
  4. Stream once to quarantine while calculating SHA-256.
  5. Verify actual byte length.
  6. Detect known signatures.
  7. Compare declared type, extension and detected type.
  8. Apply policy:
    • safe raster image: eligible for inline preview;
    • PDF/Office/text/archive/config: download by default;
    • HTML/SVG/script/executable: download-only or reject according to policy;
    • unknown: application/octet-stream, download-only.
  9. Atomically commit blob and logical reference.
  10. Generate preview asynchronously where supported.
  11. Remove quarantine data on every failure/cancellation.

Default maximum: 100 MiB per file, configurable by administrator. The reverse proxy, Kestrel and application limits must agree.

Supported initial categories

  • PNG, JPEG, GIF, WebP;
  • PDF;
  • plain text and common configuration files;
  • Office documents;
  • common archives as opaque downloads;
  • other opaque files by administrator policy.

SVG is not rendered inline in v1. Archives are not extracted as ordinary attachments.

Serving

Every content request re-authorizes the logical reference.

Headers:

  • X-Content-Type-Options: nosniff;
  • safe Content-Disposition;
  • bounded cache policy for private content;
  • CSP/sandbox where inline documents are later enabled;
  • no user-controlled response headers.

Inline rendering is initially restricted to known safe raster images. Range requests may be added for large downloads with authorization tests.

Deduplication

Two logical references may point to one blob.

  • Deduplication is global inside the installation storage, but authorization always uses the logical reference.
  • A caller cannot discover whether a matching private blob already exists.
  • Content hash is not sufficient permission to retrieve.
  • Concurrent uploads with the same SHA-256 serialize the blob lookup, atomic commit and database insert. Every upload receives its own logical reference while exactly one physical blob is retained; uploads with different hashes remain concurrent.
  • Blob cleanup occurs only when no active or retained reference remains.
  • Reference counts are derived or transactionally maintained and periodically verified.

Image metadata

Logical references may store:

  • alt text;
  • caption;
  • width/height;
  • rotation-normalized preview;
  • uploader and upload time.

Strip unnecessary metadata from generated previews. Preserve the original bytes as the blob unless policy explicitly rejects them.

Integrity

  • New blobs are verified after atomic move.
  • Scheduled sampling/full scan recalculates hashes.
  • Missing/corrupt blobs mark references degraded and alert administrators.
  • Backups include a blob manifest and hashes.
  • Restore validates before enabling normal write traffic.

Deletion

Deleting an attachment use/reference is logical first. Retention protects accidental deletion. Orphan physical blobs are cleaned in a background job after the configured window and a final transactional reference check.

Security tests

Include:

  • double extensions;
  • path traversal names;
  • null/control characters;
  • oversized/chunked uploads;
  • declared/detected MIME mismatch;
  • HTML/SVG stored XSS;
  • polyglot samples where feasible;
  • executable/script files;
  • authorization ID substitution;
  • interrupted upload cleanup;
  • duplicate content;
  • concurrent duplicate uploads;
  • malicious archive names without extraction;
  • race between deletion and download;
  • corruption detection.