Repository navigation
Open only viewable attachments, and mark every download - #560
Conversation
Pressing Enter on an attachment in the TUI now opens it only when it is a document, image, audio or video file. Anything else, such as a script, a shortcut, an installer or a Terminal profile, is left for the reader to save with s and open deliberately. The list of openable types is closed on purpose: the kinds of file an operating system will run keep growing, so naming the safe ones holds up better than naming the rest. Every attachment saved from HEY, by the TUI or by `hey attachment save`, is now marked as downloaded from the internet before it appears at its destination: the com.apple.quarantine attribute on macOS, and a Zone.Identifier stream on Windows. The system then warns before running it, as it would for a browser download. On macOS a save that can't be marked is abandoned rather than kept unmarked. Saved attachments still carry no execute permission. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The test only checked the end of the flag, so a wrong flag value that macOS ignores would still pass. It now also checks the value starts with the flag a browser sets on a download. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Linux, xdg-open picks the application from what a file contains, not from its name, so a Windows program called report.pdf passed the extension check and reached whatever handles Windows programs, such as Wine. Before handing a file to xdg-open, the TUI now asks xdg-mime what it is -- the same question xdg-open asks, through the same desktop backend -- and opens it only when the answer is a document, image or media type as well. A zip-based document that the sniffer calls application/zip still opens, in an archive manager at worst. If xdg-mime can't answer, the attachment is refused and left to s. macOS and Windows choose by extension, so nothing changes there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
All reported issues were addressed across 14 files
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
There was a problem hiding this comment.
🟡 Changes recommended
CLI documentation is incomplete, and the TUI documentation overstates Windows marking guarantees.
2 open findings
What changed in this PR
Restricts automatic attachment opening to viewer-safe formats and marks downloads with platform security metadata.
Changes:
- Adds extension and Linux MIME safety checks.
- Applies macOS quarantine and Windows zone metadata.
- Adds platform tests and updates TUI documentation.
[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or rungh pr ready --undo.
Click "Ready for review" or rungh pr readyto reengage.
| File | Description |
|---|---|
internal/tui/open_file.go |
Validates Linux MIME types before opening. |
internal/tui/open_file_test.go |
Tests Linux content checks and launching. |
internal/tui/mail.go |
Rejects unsafe attachment extensions before download. |
internal/tui/mail_test.go |
Tests unsafe attachment refusal. |
internal/attachments/viewable.go |
Defines allowed extensions and MIME types. |
internal/attachments/viewable_test.go |
Tests viewer-safety classifications. |
internal/attachments/save.go |
Marks downloaded files before installation. |
internal/attachments/save_unix_test.go |
Verifies non-executable permissions. |
internal/attachments/save_test.go |
Tests marking order and failure cleanup. |
internal/attachments/save_darwin_test.go |
Verifies macOS quarantine metadata. |
internal/attachments/mark_downloaded_windows.go |
Writes Windows zone metadata. |
internal/attachments/mark_downloaded_other.go |
Provides unsupported-platform behavior. |
internal/attachments/mark_downloaded_darwin.go |
Applies macOS quarantine metadata. |
docs/tui.md |
Documents safer attachment handling. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

What changes
attachments.OpensInViewer, a closed list of extensions checked on the sanitized filename). Any other attachment isn't downloaded; the TUI says it could run a program and to presssto save it. Zip, HTML, SVG and legacy Office attachments now needsand a manual open.xdg-openpicks the application from a file's contents rather than its name, so the TUI first asksxdg-mime query filetype— the same question, through the same desktop backend — and opens the file only if the answer is a document, image or media type too. Zip-based documents that come back asapplication/zipstill open; ifxdg-mimecan't answer, the attachment is left tos.hey attachment savealike:com.apple.quarantineon macOS (a save that can't be marked is abandoned) and aZone.Identifierstream on Windows (best effort). The system then warns before running a saved file, as it does for a browser download.Testing
make check race-test coverage check-surface-compat check-size test-e2epass..terminalfile was stopped by Gatekeeper, an unmarked copy was not.Summary by cubic
Pressing Enter on an attachment in the TUI now opens it only when it's a document, image, audio, or video, based on a closed list of safe extensions. Anything that could run a program — scripts, shortcuts, Terminal profiles, installers — must be saved with
sand opened by hand.xdg-mimewhat the file's contents are before opening it, so a program disguised as a PDF won't be launched.com.apple.quarantineon macOS (a save that can't be marked is abandoned) and aZone.Identifierstream on Windows (best effort).Written for commit 321fb25. Summary will update on new commits.