CVE-2026-47121
Full vulnerability record from the local CVENow database.
Description
Sparkle is a software update framework for macOS. Prior to version 2.9.2, `Autoupdate/SUBinaryDeltaApply.m` enforces `relativePath.pathComponents containsObject:@".."` and rejects writes whose immediate parent directory IS itself a symbolic link, but does not detect symlinks deeper in the relative path. `Autoupdate/SPUSparkleDeltaArchive.m`'s `extractItem:` will create symlinks in the destination tree from archive content (no `..` check on the symlink target), and a subsequent `Extract` item targeting `<symlink>/foo/bar` then escapes the destination tree via `fopen(path, "wb")` because the kernel resolves the intermediate symlink during the open call. This is a defense-in-depth issue: exploitation requires a maliciously-crafted `.delta` that passes EdDSA signature verification, i.e. EdDSA private-key compromise. With the AppInstaller running as root for system-domain installs, it gives the holder of a stolen signing key arbitrary file write at root level via the delta-apply path, which is a strictly broader primitive than the "drop-in replacement bundle" install they would otherwise have. Version 2.9.2 contains a patch for the issue.
View original CVE JSON
{
"id": "CVE-2026-47121",
"sourceIdentifier": "[email protected]",
"published": "2026-07-21T14:16:34.387",
"lastModified": "2026-10-24T20:10:00.137",
"vulnStatus": "Analyzed",
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "Sparkle is a software update framework for macOS. Prior to version 2.9.2, `Autoupdate/SUBinaryDeltaApply.m` enforces `relativePath.pathComponents containsObject:@\"..\"` and rejects writes whose immediate parent directory IS itself a symbolic link, but does not detect symlinks deeper in the relative path. `Autoupdate/SPUSparkleDeltaArchive.m`'s `extractItem:` will create symlinks in the destination tree from archive content (no `..` check on the symlink target), and a subsequent `Extract` item targeting `<symlink>/foo/bar` then escapes the destination tree via `fopen(path, \"wb\")` because the kernel resolves the intermediate symlink during the open call. This is a defense-in-depth issue: exploitation requires a maliciously-crafted `.delta` that passes EdDSA signature verification, i.e. EdDSA private-key compromise. With the AppInstaller running as root for system-domain installs, it gives the holder of a stolen signing key arbitrary file write at root level via the delta-apply path, which is a strictly broader primitive than the \"drop-in replacement bundle\" install they would otherwise have. Version 2.9.2 contains a patch for the issue."
},
{
"lang": "es",
"value": "Sparkle es un framework de actualización de software para macOS. Antes de la versión 2.9.2, ’Autoupdate/SUBinaryDeltaApply.m’ aplica ’relativePath.pathComponents containsObject:’..’ y rechaza escrituras cuyo directorio padre inmediato ES en sí mismo un enlace simbólico, pero no detecta enlaces simbólicos más profundos en la ruta relativa. El ’extractItem:’ de ’Autoupdate/SPUSparkleDeltaArchive.m’ creará enlaces simbólicos en el árbol de destino a partir del contenido del archivo (sin verificación de ’..’ en el objetivo del enlace simbólico), y un elemento ’Extract’ posterior que apunte a ’[symlink]/foo/bar’ escapará del árbol de destino a través de ’fopen(path, “wb”)’ porque el kernel resuelve el enlace simbólico intermedio durante la llamada de apertura. Este es un problema de defensa en profundidad: la explotación requiere un ’.delta’ manipulado maliciosamente que pase la verificación de firma EdDSA, es decir, el compromiso de la clave privada EdDSA. Con el AppInstaller ejecutándose como root para instalaciones de dominio del sistema, otorga al poseedor de una clave de firma robada la capacidad de escritura arbitraria de archivos a nivel de root a través de la ruta de aplicación de delta, lo cual es una primitiva estrictamente más amplia que la instalación de ’paquete de reemplazo directo’ que tendrían de otra manera. La versión 2.9.2 contiene un parche para el problema."
}
],
"affected": [
{
"source": "[email protected]",
"affectedData": [
{
"vendor": "sparkle-project",
"product": "Sparkle",
"versions": [
{
"version": "< 2.9.2",
"status": "affected"
}
]
}
]
}
],
"metrics": {
"cvssMetricV31": [
{
"source": "[email protected]",
"type": "Secondary",
"cvssData": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:N/I:H/A:N",
"baseScore": 6.1,
"baseSeverity": "MEDIUM",
"attackVector": "NETWORK",
"attackComplexity": "HIGH",
"privilegesRequired": "NONE",
"userInteraction": "REQUIRED",
"scope": "CHANGED",
"confidentialityImpact": "NONE",
"integrityImpact": "HIGH",
"availabilityImpact": "NONE"
},
"exploitabilityScore": 1.6,
"impactScore": 4.0
}
],
"ssvcV203": [
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"ssvcData": {
"timestamp": "2026-07-22T14:30:24.947456Z",
"id": "CVE-2026-47121",
"options": [
{
"exploitation": "poc"
},
{
"automatable": "no"
},
{
"technicalImpact": "partial"
}
],
"role": "CISA Coordinator",
"version": "2.0.3"
}
}
]
},
"weaknesses": [
{
"source": "[email protected]",
"type": "Secondary",
"description": [
{
"lang": "en",
"value": "CWE-22"
},
{
"lang": "en",
"value": "CWE-59"
}
]
}
],
"configurations": [
{
"nodes": [
{
"operator": "OR",
"negate": false,
"cpeMatch": [
{
"vulnerable": true,
"criteria": "cpe:2.3:a:sparkle-project:sparkle:*:*:*:*:*:*:*:*",
"versionEndExcluding": "2.9.2",
"matchCriteriaId": "68782F57-D50F-4F2F-B152-902FA2CB92C6"
}
]
}
]
}
],
"references": [
{
"url": "https://github.com/sparkle-project/Sparkle/commit/fe7b718d0736f3e139e374e26fbca96f29e13bf0",
"source": "[email protected]",
"tags": [
"Patch"
]
},
{
"url": "https://github.com/sparkle-project/Sparkle/security/advisories/GHSA-hg88-v3cw-3qrh",
"source": "[email protected]",
"tags": [
"Vendor Advisory"
]
},
{
"url": "https://github.com/sparkle-project/Sparkle/security/advisories/GHSA-hg88-v3cw-3qrh",
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"tags": [
"Vendor Advisory"
]
}
]
}