Summary
Security regression review found that the privileged helper Mach service is created without a client code-signing requirement, while exposing handlers that can perform privileged file operations and dylib injection.
Affected code:
RuntimeViewerPackages/Sources/RuntimeViewerService/RuntimeViewerService.swift: XPCListener(type: .machService(...), codeSigningRequirement: nil)
RuntimeViewerPackages/Sources/RuntimeViewerService/RuntimeViewerService.swift: fileOperation supports create/remove/move/copy/write using request-provided URLs
RuntimeViewerPackages/Sources/RuntimeViewerService/RuntimeViewerService.swift: injectApplication calls MachInjector.inject(pid:dylibPath:) using request-provided input
Impact
If the privileged helper is installed and reachable, an arbitrary local process may be able to connect to the Mach service and invoke sensitive helper operations unless SwiftyXPC or another layer is enforcing client validation elsewhere. I did not run a destructive proof-of-concept; this is a source-level security finding from the current service setup.
Recommended Fix
- Require an explicit code signing requirement on the privileged Mach service listener for the expected RuntimeViewer app identities and Team ID.
- If SwiftyXPC exposes audit-token/client identity APIs, validate the connecting client per connection as defense in depth.
- Restrict
FileOperationRequest to the exact app-controlled paths the helper is expected to manage, instead of accepting arbitrary URLs.
- Validate
InjectApplicationRequest.dylibURL against the expected signed RuntimeViewer payload path before injection.
- Add regression tests that assert untrusted clients are denied and out-of-scope file paths are rejected.
Regression Context
Security pass performed locally:
- Secret scan: no committed private key/token found.
- OSV dependency query: no known vulnerabilities returned for the locked dependency set.
RuntimeViewerCore: swift test passed, 427 tests.
RuntimeViewerPackages: swift test passed, 18 tests.
RuntimeViewerMCP: swift test currently fails dependency resolution because SwiftMCP 1.4.x and MachOSwiftSection require incompatible swift-syntax ranges.
- Xcode debug build succeeded with code signing disabled after building
RuntimeViewerCatalystHelper first, then RuntimeViewer macOS. A normal signed local build was blocked only by a missing local Mac Development certificate/private key.
Summary
Security regression review found that the privileged helper Mach service is created without a client code-signing requirement, while exposing handlers that can perform privileged file operations and dylib injection.
Affected code:
RuntimeViewerPackages/Sources/RuntimeViewerService/RuntimeViewerService.swift:XPCListener(type: .machService(...), codeSigningRequirement: nil)RuntimeViewerPackages/Sources/RuntimeViewerService/RuntimeViewerService.swift:fileOperationsupports create/remove/move/copy/write using request-provided URLsRuntimeViewerPackages/Sources/RuntimeViewerService/RuntimeViewerService.swift:injectApplicationcallsMachInjector.inject(pid:dylibPath:)using request-provided inputImpact
If the privileged helper is installed and reachable, an arbitrary local process may be able to connect to the Mach service and invoke sensitive helper operations unless SwiftyXPC or another layer is enforcing client validation elsewhere. I did not run a destructive proof-of-concept; this is a source-level security finding from the current service setup.
Recommended Fix
FileOperationRequestto the exact app-controlled paths the helper is expected to manage, instead of accepting arbitrary URLs.InjectApplicationRequest.dylibURLagainst the expected signed RuntimeViewer payload path before injection.Regression Context
Security pass performed locally:
RuntimeViewerCore:swift testpassed, 427 tests.RuntimeViewerPackages:swift testpassed, 18 tests.RuntimeViewerMCP:swift testcurrently fails dependency resolution becauseSwiftMCP 1.4.xandMachOSwiftSectionrequire incompatibleswift-syntaxranges.RuntimeViewerCatalystHelperfirst, thenRuntimeViewer macOS. A normal signed local build was blocked only by a missing localMac Developmentcertificate/private key.