Skip to content

fix: Harden socket security and add hook installation consent#48

Open
pablotp wants to merge 1 commit into
farouqaldori:mainfrom
pablotp:fix/security-hardening
Open

fix: Harden socket security and add hook installation consent#48
pablotp wants to merge 1 commit into
farouqaldori:mainfrom
pablotp:fix/security-hardening

Conversation

@pablotp

@pablotp pablotp commented Feb 23, 2026

Copy link
Copy Markdown

Summary

  • Moves the Unix domain socket from world-accessible /tmp/ to the user-scoped ~/.claude/ directory
  • Adds token-based authentication to prevent unauthorized processes from sending events to the app
  • Restricts socket file permissions from 0o777 to 0o600 (owner-only)
  • Adds a first-launch consent dialog before installing hooks into the user's Claude Code configuration

Changes

  • HookSocketServer.swift: Move socket path from /tmp/claude-island.sock to ~/.claude/claude-island.sock; generate a random auth token on server start, write it to ~/.claude/hooks/.claude-island-token with 0o600 permissions; validate the token on every incoming
    connection and reject unauthorized events; clean up legacy /tmp/ socket on start; add token field to HookEvent
  • claude-island-state.py: Update socket path to ~/.claude/claude-island.sock; read auth token from ~/.claude/hooks/.claude-island-token and include it in every event sent to the app
  • Settings.swift: Add hooksConsentGiven setting (tri-state: nil = never asked, true = consented, false = declined)
  • AppDelegate.swift: Replace direct HookInstaller.installIfNeeded() call with installHooksWithConsent() that checks consent state, grants implied consent to existing users who already have hooks installed, and shows a consent dialog for new users
  • NotchMenuView.swift: Sync the hooks toggle in the settings menu with the consent state

Security considerations

  • The previous socket at /tmp/claude-island.sock with 0o777 permissions allowed any process on the system to send events, potentially injecting fake permission approvals
  • The new location under ~/.claude/ with 0o600 permissions restricts access to the current user
  • The token authentication adds defense in depth: even if another process can access the socket, it cannot send valid events without reading the token file (also 0o600)
  • The consent dialog ensures hooks are not silently installed into the user's Claude Code configuration on first launch

@pablotp pablotp changed the title Harden socket security and add hook installation consent fix: Harden socket security and add hook installation consent Feb 23, 2026
- Change Unix socket permissions from 0o777 to 0o600 (owner-only)
- Move socket from /tmp/claude-island.sock to ~/.claude/claude-island.sock
- Add token-based authentication to the socket protocol
- Require user consent before modifying ~/.claude/settings.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@pablotp pablotp force-pushed the fix/security-hardening branch from 012ef9e to e461a4c Compare February 25, 2026 10:40
@pablotp

pablotp commented Feb 25, 2026

Copy link
Copy Markdown
Author

@farouqaldori JFYI I have been testing #53 #52 #51 and #48 together on my machine (Mac Tahoe 26.3) for the last 2 days and are working without issues.

Thanks for creating this amazing project!

rosuH pushed a commit to rosuH/claude-island that referenced this pull request Apr 14, 2026
…ri#48)

* refactor(perf): adopt Swift 6.2 concurrency and performance patterns

- Fix ConversationParser actor starvation by extracting file I/O into
  nonisolated static methods, preventing actor lock during disk ops
- Add swift-subprocess package for async process execution, replacing
  Foundation.Process + DispatchQueue boilerplate in ProcessExecutor
- Optimize HookSocketServer buffer with withUnsafeTemporaryAllocation
  for stack allocation instead of per-read heap allocation
- Use lazy split() in incremental parsing to avoid full array allocation
- Move NotchHeaderView animation arrays to static properties

* perf: implement Swift 6.2 performance optimizations

- Cache LCS computation in SimpleDiffView to avoid redundant calculations
- Use space-optimized LCS algorithm with UInt8 direction matrix
- Add ProcessTree struct with O(1) parent→children index for descendant lookup
- Replace components(separatedBy:) with split() for efficient Substring handling
- Add reserveCapacity() calls for predictable array sizes
- Unify ClaudeSessionMonitor Task bridging to reduce executor hops
- Document @Concurrent candidates in ProcessExecutor for Swift 6.2 adoption

* perf: add Swift 6.2 concurrency optimizations

- Enable nonisolated(nonsending) by default via compiler flag
- Enable global concurrency feature for @Concurrent attribute support
- Add @Concurrent to ProcessExecutor async methods for explicit concurrent execution
- Defer String allocation in ConversationParser incremental parsing hot path

* Address review comments from PR farouqaldori#48

- Fix SimpleDiffView computed property recomputation: cachedDiffResult was
  a computed property, causing the expensive LCS algorithm to run multiple
  times per render pass. Now computed once at the start of body.

- Fix misleading "off-actor" comment in ConversationParser: nonisolated
  static methods called synchronously from within an actor still execute
  on the actor's executor. Updated documentation to accurately describe
  the behavior.

- Fix processIncrementalContent returning all messages on no-op reads:
  when there's no new content, the function now returns an empty array
  instead of state.messages, which would incorrectly report all messages
  as "new" in the IncrementalParseResult.newMessages field.
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