Skip to main content

Overview

Rockxy terminates TLS, stores sensitive traffic, and communicates with a root-privileged helper. Security is layered across every boundary.

Security Boundaries

BoundaryRiskControl
App to helperUntrusted app attempts privileged proxy/cert operationsNSXPCConnection with code-signing requirements + helper-side connection validation + certificate-chain comparison
TLS interceptionInvalid or stale root CA causes broken trust or confusing MITM stateExplicit root CA lifecycle, trust checks, root fingerprint tracking, per-host cert issuance from active root only
Request body handlingMemory exhaustion via oversized bodies100 MB request body cap (413 rejection), 8 KB URI length cap (414 rejection), WebSocket frame limits (10 MB/frame, 100 MB/connection)
Map Local file servingPath traversal or symlink escapefd-based file loading (eliminates TOCTOU), symlink resolution, rooted path containment checks
Rule regex patternsReDoS from pathological regexCompile-time validation, pre-compiled cache, 500-char pattern limit, 8 KB input cap
Breakpoint editsMalformed request forwarding after URL/header/body editsCentralized rebuilding in BreakpointRequestBuilder, authority preservation, scheme normalization, content-length reconciliation
Plugin executionScripts mutating traffic unsafelyJavaScriptCore bridge, bounded hook API, 5-second timeout, plugin ID/key validation, no filesystem/network access
Stored trafficSensitive bodies kept too long or with weak permissionsIn-memory buffering + disk/SQLite persistence, large-body offload with 0o600 file permissions, path containment on load/delete, log credential redaction
Header injectionCRLF injection via MapRemote host headerHeader value sanitization stripping control characters before forwarding
Helper input validationMalformed domains or service names passed to networksetupASCII-only bypass domain validation, service name sanitization, proxy type whitelisting, domain count limits

Helper Trust Model

The helper runs as a launchd daemon (com.amunx.Rockxy.HelperTool) registered via SMAppService.daemon(). It exists so proxy override and certificate operations can be performed without repeated networksetup password prompts. Defense-in-depth includes:
  • App-side privileged XPC connection setup
  • Caller validation in Shared/ConnectionValidator.swift checks the caller against the configured set of allowed bundle identifiers (loaded from RockxyIdentity.current.allowedCallerIdentifiers)
  • Code-signing requirement enforcement (anchor apple generic)
  • Certificate-chain comparison — trust is not based only on bundle ID or team ID strings
  • Helper-side rate limiting for state-changing operations (proxy changes, certificate installs)
  • Input validation on all helper parameters (bypass domains, service names, proxy types)
  • Atomic temp file creation with restricted permissions (0o600)
  • Explicit proxy backup/restore paths for crash recovery

Certificate Trust Model

  • Root CA generation and persistence live in CertificateManager
  • The app owns root CA creation, loading, and trust-state verification
  • The helper assists with privileged keychain/system install operations, but trust has an app-visible verification path
  • Host certificates are generated on demand from the current root and cached (LRU ~1,000 entries)
  • Root fingerprint tracking cleans up stale certificates and reduces “multiple old Rockxy roots installed” drift

Practical Security Notes

Rockxy is a developer tool with access to sensitive traffic. Do not leave system proxy override enabled longer than needed.
  • Installing the root CA enables HTTPS interception only for clients that trust that root
  • Saved sessions, exports, and plugin code should be treated as potentially sensitive project artifacts
  • The privileged helper validates every connection via certificate-chain comparison, not just bundle ID

Vulnerability Reporting

If you discover a security issue, please report it privately via SECURITY.md.

Next Steps

Architecture

Proxy engine, actor model, and data flow

Design Decisions

Why SwiftNIO, NSTableView, actors, and the helper daemon