Skip to content

Fix clipboard privacy issues: content logging, concealed-type gating, settings crash#5

Open
MiMoHo wants to merge 1 commit into
haad:masterfrom
MiMoHo:clipboard-privacy-fixes
Open

Fix clipboard privacy issues: content logging, concealed-type gating, settings crash#5
MiMoHo wants to merge 1 commit into
haad:masterfrom
MiMoHo:clipboard-privacy-fixes

Conversation

@MiMoHo

@MiMoHo MiMoHo commented Jul 3, 2026

Copy link
Copy Markdown

Summary

Three fixes for handling of potentially sensitive clipboard data, found during a security review of the codebase:

  1. Stop logging clipping contents to the unified log. pasteFromStack logged the first 50 characters of every clipping pasted via the bezel through NSLog — in release builds. Unified log entries are readable via Console/log show and end up in sysdiagnose bundles, so short secrets (passwords, tokens) leaked in full on every paste.

  2. Honor the nspasteboard.org skip types independently of the password-fields toggle. The org.nspasteboard.ConcealedType/TransientType/AutoGeneratedType check was nested inside the skipPasswordFields conditional, so unchecking the innocuously-labeled "Don't copy from password fields" box silently disabled all password-manager protection. The type-based skip now runs on its own skipPboardTypes setting, as the two separate preferences imply. The revealPasteboardTypes debug aid also no longer triggers a store modification/save on every poll evaluation.

  3. Fix invalid -setValue: calls in setSavePreference:. Two calls were missing forKey: — an unrecognized-selector exception if that path executes, leaving the iCloud-sync/save-preference interlock unapplied.

Testing

clang -fsyntax-only against the macOS SDK shows no new diagnostics versus master (the two setValue: warnings on master disappear with fix 3). No full local xcodebuild available on this machine; behavior changes are small and localized.

🤖 Generated with Claude Code

Three fixes for handling of potentially sensitive clipboard data:

- Stop logging clipping contents on paste.  pasteFromStack wrote the
  first 50 characters of every pasted clipping to the unified log via
  NSLog in release builds, where other processes, Console, and
  sysdiagnose bundles can read it.  Short secrets (passwords, tokens)
  leaked in full.

- Honor the nspasteboard.org skip types independently of the
  'Don't copy from password fields' toggle.  The ConcealedType/
  TransientType/AutoGeneratedType check was nested inside the
  skipPasswordFields conditional, so unchecking that one box silently
  disabled all password-manager protection.  The revealPasteboardTypes
  side effect also no longer runs (with a store save) on every poll.

- Fix invalid -setValue: calls (missing forKey:) in setSavePreference:
  that would raise unrecognized-selector and leave the iCloud-sync/
  save-preference interlock unapplied.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MiMoHo

MiMoHo commented Jul 3, 2026

Copy link
Copy Markdown
Author

@haad — one topic beyond this PR's scope, posted here because the Issues tab is disabled on this repo (forks have it off by default; it can be enabled under Settings → General → Features, happy to move this there):

Release signing: Developer ID + notarization (and a path to becoming the Homebrew default)

Current state

  • release.yml signs with whatever certificate is in secrets.CERTIFICATES_P12, falling back to ad-hoc (CODE_SIGN_IDENTITY="-"), and has no notarization step (no notarytool/stapler anywhere)
  • The project itself is configured with CODE_SIGN_IDENTITY = "Apple Development" — a development certificate, not Developer ID Application
  • RELEASE_SETUP.md describes a release-signed.yml workflow with NOTARIZATION_* secrets, but that workflow file does not exist — docs and pipeline have diverged

Why it matters

Gatekeeper blocks non-notarized DMGs on other machines ("damaged"/"unverified developer"), so every user must right-click-open or strip the quarantine attribute. For a clipboard manager — an app that sees every password and token a user copies — training users to bypass Gatekeeper is exactly the wrong habit, and it removes the one cryptographic assurance that a downloaded binary matches this source.

The Homebrew angle

The official flycut cask still points to the abandoned TermiT release 1.9.6 from years ago. This fork is the natural successor, and a brew upgrade path would give it real reach — but a cask that immediately triggers Gatekeeper warnings is a hard sell to Homebrew maintainers. With notarized artifacts, updating the existing cask (or shipping a tap) becomes straightforward.

Concrete steps

  1. Enroll in the Apple Developer Program (if not already) and create a Developer ID Application certificate; put it in CERTIFICATES_P12
  2. In release.yml, after signing:
    xcrun notarytool submit Flycut.dmg --apple-id "$APPLE_ID" --team-id "$TEAM_ID" --password "$APP_SPECIFIC_PASSWORD" --wait
    xcrun stapler staple Flycut.dmg
    
  3. Remove the ad-hoc fallback (better to fail the release than ship an unsigned artifact silently), and reconcile RELEASE_SETUP.md with the actual workflow
  4. Optional hardening: pin the GitHub Actions to commit SHAs and a fixed Xcode version for reproducibility

I'm happy to prepare the workflow changes as a PR — steps 2–4 are mechanical; only the certificate/account part (step 1) has to come from you.

🤖 Generated with Claude Code

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.

1 participant