Skip to content

[codex] Harden Quick Look preview sandbox#385

Merged
schuyler merged 2 commits into
schuyler:mainfrom
yusufm:Codex/harden-quicklook-preview-019da736-8573-7ac1-9883-259ce39e964a
Apr 19, 2026
Merged

[codex] Harden Quick Look preview sandbox#385
schuyler merged 2 commits into
schuyler:mainfrom
yusufm:Codex/harden-quicklook-preview-019da736-8573-7ac1-9883-259ce39e964a

Conversation

@yusufm

@yusufm yusufm commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • disable content JavaScript in the Quick Look WKWebView and cancel non-local navigations
  • add a restrictive Content Security Policy to Quick Look HTML output
  • stop embedding Prism scripts in Quick Look and remove the extension network-client entitlement
  • add renderer tests covering the CSP and the absence of embedded Quick Look scripts

Why

Quick Look was rendering attacker-controlled Markdown into a live WKWebView with script execution paths and outbound network capability. A malicious file previewed in Finder could execute JavaScript and exfiltrate document content without opening the main app.

Root cause

The Quick Look path reused the normal rendered HTML body, appended executable Prism scripts, left WebKit JavaScript enabled, and shipped a sandbox entitlement for outbound network access.

Validation

  • xcodebuild test -workspace "MacDown 3000.xcworkspace" -scheme MacDown -destination "platform=macOS"
  • 257 tests passed, 0 failures

@yusufm yusufm marked this pull request as ready for review April 19, 2026 22:47

Copy link
Copy Markdown
Owner

Nice layered hardening — CSP + disabled JS + nav-cancel + entitlement drop is solid defense in depth, and I like that tests cover both the CSP presence and the absence of embedded Prism scripts.

A few non-blocking observations:

  • -[MPQuickLookRenderer embeddedScripts] (MPQuickLookRenderer.m:419) and any now-unused Prism helpers appear to be dead code after this change. Worth pruning in a follow-up so the attack surface stays trimmed.
  • config.preferences.javaScriptEnabled = NO is deprecated on macOS 11+. Correct for backward compat, but may produce a build warning; an @available else-branch or a pragma would keep the build clean.
  • Allowing data: in decidePolicyForNavigationAction: is safe given the CSP and JS-off posture, but a one-line comment explaining why it's allowed would help future readers.

None of these are blockers — LGTM.


Generated by Claude Code

@schuyler schuyler merged commit db0716b into schuyler:main Apr 19, 2026
5 checks passed
@yusufm yusufm deleted the Codex/harden-quicklook-preview-019da736-8573-7ac1-9883-259ce39e964a branch April 19, 2026 22:57
@schuyler schuyler added the rc-pending Included in a release candidate awaiting validation label Jun 26, 2026
schuyler added a commit that referenced this pull request Jun 30, 2026
## Summary

- Add MacDownCore (framework) and MacDownQuickLook (app extension) as
native targets in the Xcode project
- Wire CocoaPods dependencies for both targets
- Embed the Quick Look extension in the main app bundle
- Remove `public.text` from `QLSupportedContentTypes` so the extension
only claims markdown files

## Background

The Quick Look source code was merged in PRs #299, #368, and #385 but
the Xcode project was never configured to build it. This caused 3000.0.6
to register the QL handler without providing a working preview — worse
than the macOS default.

## Key decisions

- **Resource copying via script phase**: MacDownCore copies Styles and
Prism resources via its own shell script build phase rather than reusing
MacDown's PBXFileReferences. Those refs are declared outputs of
MacDown's "Fetch Prism Resources" and "Transpile Styles" script phases,
which would create a dependency cycle.
- **No MacDown→MacDownCore dependency**: The main app only depends on
MacDownQuickLook. MacDownCore is embedded inside the extension only,
since only the extension uses it.
- **Per-configuration bundle IDs**: Debug uses `-debug` suffix to match
the parent app's pattern.

## Test plan

- [ ] `xcodebuild build` succeeds (verified locally)
- [ ] 1003 tests pass with 0 unexpected failures (verified locally)
- [ ] `.app` bundle contains `MacDownQuickLook.appex` in
`Contents/PlugIns/` (verified locally)
- [ ] `MacDownQuickLook.appex` contains `MacDownCore.framework` with
`Styles/` and `Prism/` resources (verified locally)
- [ ] Quick Look preview renders markdown files in Finder
- [ ] Quick Look does NOT activate for `.txt`, `.csv`, or other
non-markdown text files

Related to #284
schuyler added a commit that referenced this pull request Jun 30, 2026
## Summary

- Add MacDownCore (framework) and MacDownQuickLook (app extension) as
native targets in the Xcode project
- Wire CocoaPods dependencies for both targets
- Embed the Quick Look extension in the main app bundle
- Remove `public.text` from `QLSupportedContentTypes` so the extension
only claims markdown files

## Background

The Quick Look source code was merged in PRs #299, #368, and #385 but
the Xcode project was never configured to build it. This caused 3000.0.6
to register the QL handler without providing a working preview — worse
than the macOS default.

## Key decisions

- **Resource copying via script phase**: MacDownCore copies Styles and
Prism resources via its own shell script build phase rather than reusing
MacDown's PBXFileReferences. Those refs are declared outputs of
MacDown's "Fetch Prism Resources" and "Transpile Styles" script phases,
which would create a dependency cycle.
- **No MacDown→MacDownCore dependency**: The main app only depends on
MacDownQuickLook. MacDownCore is embedded inside the extension only,
since only the extension uses it.
- **Per-configuration bundle IDs**: Debug uses `-debug` suffix to match
the parent app's pattern.

## Test plan

- [ ] `xcodebuild build` succeeds (verified locally)
- [ ] 1003 tests pass with 0 unexpected failures (verified locally)
- [ ] `.app` bundle contains `MacDownQuickLook.appex` in
`Contents/PlugIns/` (verified locally)
- [ ] `MacDownQuickLook.appex` contains `MacDownCore.framework` with
`Styles/` and `Prism/` resources (verified locally)
- [ ] Quick Look preview renders markdown files in Finder
- [ ] Quick Look does NOT activate for `.txt`, `.csv`, or other
non-markdown text files

Related to #284
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rc-pending Included in a release candidate awaiting validation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants