Skip to content

feat: implement modular content scanning pipeline for image validatio… - #622

Merged
Qoder-Undefined merged 1 commit into
MERIDIAN-CITY:mainfrom
A-one-tech:feature/secure-upload-pipeline
Jul 28, 2026
Merged

feat: implement modular content scanning pipeline for image validatio…#622
Qoder-Undefined merged 1 commit into
MERIDIAN-CITY:mainfrom
A-one-tech:feature/secure-upload-pipeline

Conversation

@A-one-tech

Copy link
Copy Markdown

#Closes
#613

Pull Request: Secure Upload Pipeline (Scanners, Deduplication & Sanitization)

Description

This Pull Request secures the file upload endpoint in meridian-api against malicious payloads, image decompression bombs, stored XSS / file-name reflection vectors, and prevents duplicated object store usage.


Key Changes

1. Strategy Interface & Content Scanners

  • ContentScanner Strategy: Created a strategy interface ContentScanner under content-scanner.interface.ts.
  • Decompression Bomb Protection (ImageDimensionsScanner): Checks logical screen dimensions for PNG, GIF, and JPEG images by stream-decoding header metadata from raw file buffers in image-dimensions.scanner.ts. Avoids loading the full pixel array into memory, fast-failing if width or height exceeds limits (default 4096px).
  • Antivirus Integration (ClamAvScanner): Implemented clamd antivirus scan in clam-av.scanner.ts using INSTREAM protocol over TCP. Falls back to spawning a local clamscan child process on temporary workspace files if TCP clamd is not configured.

2. Idempotency & Hashing

  • Unique Hash Deduplication: UploadService now computes a SHA-256 hash of every uploaded file buffer. If the hash matches an existing record in the database, the service immediately returns the cached URL and sanitized name, avoiding storage replication and redundant network writes.
  • Upload Entity: Added upload.entity.ts to track contentHash, url, originalName, mimeType, and size.

3. File Name Sanitization

  • Strips directory traversal path structures (e.g. ../../).
  • Enforces filename extension matches MIME type (e.g., appends/corrects .jpg for image/jpeg).
  • HTML-escapes filenames to prevent XSS reflection / stored-XSS in frontends rendering the original file name.

Security Mitigations

Threat Vulnerability Details Mitigation
Image Decompression Bombs Small files with massive pixel dimensions (e.g. 50k x 50k) leading to OOM server crash. Headers scanned pre-decode by ImageDimensionsScanner.
Malicious Payload Bypass Magic-byte checks only inspect prefix; viruses/webshells can hide inside a valid image wrapper. Full-buffer scanning via TCP/process fallback in ClamAvScanner.
Stored XSS / Reflection Filenames with HTML elements (<script>) reflect payload to client UI. Full HTML sanitization & escaping of originalName stem in UploadService.
Storage Redundancy Duplicate binary uploads consume excessive object storage and database space. SHA-256 hash check returning existing URL.

Verification

Automated Tests

The following unit test suites were added or updated to cover all scanning, sanitization, and deduplication logic:

  • src/upload/upload.service.spec.ts
  • src/upload/providers/image-dimensions.scanner.spec.ts
  • src/upload/providers/clam-av.scanner.spec.ts

Run Jest:

npx jest upload

Results:

  • 7/7 Test Suites Passed
  • 55/55 Tests Passed

Build verification:

npm run build

Results:

  • Successful NestJS compilation.

@Qoder-Undefined Qoder-Undefined left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Qoder-Undefined
Qoder-Undefined merged commit 9c7dbe9 into MERIDIAN-CITY:main Jul 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants