Skip to content

fix: sandbox PDF preview iframe to block script execution#71

Merged
overtrue merged 5 commits intomainfrom
overtrue/fix-preview-sandbox
Mar 2, 2026
Merged

fix: sandbox PDF preview iframe to block script execution#71
overtrue merged 5 commits intomainfrom
overtrue/fix-preview-sandbox

Conversation

@overtrue
Copy link
Collaborator

@overtrue overtrue commented Mar 2, 2026

Pull Request

Description

Harden object preview against stored XSS payloads in mislabelled PDF files.

Changes:

  • Require Content-Type to be actual application/pdf for PDF preview (remove .pdf extension fallback).
  • Normalize MIME parsing (application/pdf; charset=... still works).
  • Add strict sandbox="" to the preview iframe so embedded content cannot execute scripts.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • Performance improvement
  • Test improvements
  • Security fix

Testing

  • Unit tests added/updated
  • Manual testing completed

Commands executed:

pnpm install --frozen-lockfile
pnpm tsc --noEmit
pnpm eslint components/object/preview-modal.tsx
pnpm prettier --write components/object/preview-modal.tsx

Notes:

  • pnpm lint and pnpm prettier --check . currently fail on existing generated .nuxt/* files in repository baseline, unrelated to this change.
  • pnpm test:run is not available in this package.

Checklist

  • Code follows the project's style guidelines
  • Self-review completed
  • TypeScript types are properly defined
  • All commit messages are in English (Conventional Commits)
  • All existing tests pass
  • No new dependencies added, or they are justified

Related Issues

Closes #

Screenshots (if applicable)

N/A

Additional Notes

This directly mitigates the GHSA preview-path exploit condition where HTML content can be delivered under a .pdf filename and rendered in preview context.

Copilot AI review requested due to automatic review settings March 2, 2026 04:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Hardens the object preview modal against stored XSS delivered via “PDF” objects by tightening PDF detection and restricting iframe capabilities.

Changes:

  • Normalize Content-Type parsing (strip parameters and lowercase) for media type checks.
  • Require Content-Type to be exactly application/pdf (removes .pdf filename fallback) before rendering the PDF preview.
  • Add a fully sandboxed iframe for PDF preview to block script execution in embedded content.
Comments suppressed due to low confidence (1)

components/object/preview-modal.tsx:53

  • normalizedContentType is introduced to normalize/trim/lowercase the MIME type, but isText still checks contentType.startsWith(...). Using the normalized value here would keep MIME handling consistent (including case-insensitivity) and avoids subtle mismatches between the various preview type checks.
  const isText =
    objectSize <= ALLOWED_SIZE &&
    (TEXT_MIMES.some((m) => contentType.startsWith(m)) ||
      TEXT_EXTENSIONS.some((ext) => objectKey.toLowerCase().endsWith(ext)))

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@overtrue overtrue merged commit a8cff0d into main Mar 2, 2026
11 checks passed
@overtrue overtrue deleted the overtrue/fix-preview-sandbox branch March 2, 2026 04:35
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.

2 participants