CVE-2026-47121 Overview
CVE-2026-47121 is a path traversal vulnerability [CWE-22] in Sparkle, a software update framework for macOS. The flaw resides in the binary delta apply logic prior to version 2.9.2. Sparkle rejects .. path components and blocks writes when the immediate parent directory is a symbolic link, but it fails to detect symlinks located deeper in the relative path. An attacker who controls a signed .delta archive can plant a symlink and then write through it, escaping the destination tree. Exploitation requires EdDSA signing key compromise, making this a defense-in-depth issue. Because AppInstaller runs as root for system-domain installs, a stolen key holder obtains arbitrary root-level file write beyond the normal bundle replacement primitive.
Critical Impact
Attackers holding a compromised EdDSA signing key can escape the destination directory during delta application and write arbitrary files as root on macOS systems using Sparkle for system-domain updates.
Affected Products
- Sparkle software update framework for macOS versions prior to 2.9.2
- macOS applications bundling vulnerable Sparkle releases
- System-domain installers invoking AppInstaller with root privileges
Discovery Timeline
- 2026-07-21 - CVE-2026-47121 published to NVD
- 2026-07-23 - Last updated in NVD database
Technical Details for CVE-2026-47121
Vulnerability Analysis
The vulnerability exists in Sparkle's binary delta application path. Autoupdate/SUBinaryDeltaApply.m validates each archive entry's relativePath by checking that its pathComponents do not contain ... It also rejects writes when the immediate parent directory is a symlink. Neither check inspects intermediate path components for symbolic links.
Autoupdate/SPUSparkleDeltaArchive.m implements extractItem:, which materializes symlinks from archive content without validating the link target for .. sequences. A crafted archive can therefore write a symlink, for example evil -> /, into the destination tree. A subsequent Extract item referencing evil/foo/bar invokes fopen(path, "wb"). The kernel resolves the intermediate symlink during the open call and writes the file outside the intended destination.
Root Cause
Sparkle's path sanitization operates on the archive-declared relative path in isolation. It does not resolve intermediate components against the filesystem state produced by earlier archive entries. Ordering a symlink-creation item before an Extract item bypasses the checks entirely.
Attack Vector
Exploitation requires a maliciously crafted .delta archive that passes EdDSA signature verification, meaning the attacker must possess a stolen signing key. When AppInstaller executes as root for system-domain installs, the primitive escalates from a scoped bundle replacement to arbitrary file write at root.
[archive enumerateItems:^(SPUDeltaArchiveItem *item, BOOL *stop) {
NSString *relativePath = item.relativeFilePath;
- if ([relativePath.pathComponents containsObject:@".."]) {
+ NSArray<NSString *> *relativePathComponents = relativePath.pathComponents;
+ if ([relativePathComponents containsObject:@".."]) {
if (error != NULL) {
*error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileWriteUnknownError userInfo:@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Relative path '%@' contains '..' path component", relativePath] }];
}
Source: Sparkle GitHub Commit fe7b718
Detection Methods for CVE-2026-47121
Indicators of Compromise
- Files created outside the expected application bundle path during a Sparkle update operation.
- Unexpected symbolic links inside application Contents directories following a .delta install.
- AppInstaller or Autoupdate processes writing to system paths such as /Library, /etc, or /var while running as root.
Detection Strategies
- Monitor fopen, open, and symlink syscalls originating from Sparkle helper binaries and correlate targets against the expected update destination.
- Inventory macOS applications bundling Sparkle and flag any using a version earlier than 2.9.2.
- Track EdDSA signing key handling and alert on delta archive verifications that succeed for unexpected publishers.
Monitoring Recommendations
- Enable file integrity monitoring on directories updated by Sparkle-managed applications.
- Log all executions of AppInstaller and Autoupdate with full argument and parent process context.
- Alert on symlink creation events within update staging directories.
How to Mitigate CVE-2026-47121
Immediate Actions Required
- Upgrade all applications bundling Sparkle to version 2.9.2 or later.
- Audit developer environments and CI systems that hold EdDSA update signing keys for signs of compromise.
- Rotate any signing keys suspected of exposure and reissue signed update manifests.
Patch Information
Sparkle 2.9.2 contains the fix. The patch is available in the Sparkle GitHub Commit fe7b718 and documented in the Sparkle Security Advisory GHSA-hg88-v3cw-3qrh. Application vendors must rebuild and redistribute their apps against the patched framework.
Workarounds
- Store EdDSA signing keys in hardware-backed key stores or HSMs to raise the bar for key theft.
- Restrict AppInstaller root privileges by preferring user-domain installs where feasible.
- Validate delta archive contents in a sandboxed staging directory prior to applying updates system-wide.
# Verify installed Sparkle framework version inside an application bundle
/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" \
"/Applications/YourApp.app/Contents/Frameworks/Sparkle.framework/Resources/Info.plist"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

