Apr 24, 2026·5 min read·4 visits
A path traversal vulnerability in Chainguard's melange tool (CVE-2026-29051, CVSS 4.4) allows attackers to perform arbitrary JSON file writes when the `--persist-lint-results` flag is enabled, requiring an update to version 0.43.4.
Melange versions prior to 0.43.4 are vulnerable to a path traversal attack when processing untrusted APK packages with the `--persist-lint-results` flag. Attackers can manipulate the `.PKGINFO` metadata to write JSON files outside intended directories.
Melange is a utility for constructing APK packages through declarative pipelines. The software relies on metadata embedded within the .PKGINFO control file to understand package characteristics during build and linting operations. This metadata includes architectural targets and package naming conventions.
When the --persist-lint-results flag is enabled during a lint or build process, melange generates a JSON-formatted report. The application determines the output destination for this report by concatenating the base output directory with the arch and pkgname fields extracted directly from the processed package.
Because the application implicitly trusts the contents of the .PKGINFO file, an attacker can manipulate these metadata fields to manipulate the destination path. This results in a CWE-22 path traversal vulnerability, enabling the tool to write data outside of the restricted parent directory.
The core vulnerability resides within the saveLintResults function located in pkg/linter/results.go. This function processes the accumulated linting data and formats it into a JSON structure for persistent storage on the local file system.
Prior to version 0.43.4, the application extracted the arch and pkgname metadata values from the untrusted .PKGINFO file and passed them immediately to filepath.Join and os.MkdirAll. The software performed no validation or sanitization on these inputs to detect path separation characters or directory traversal sequences.
When filepath.Join processes strings containing ../, it resolves the relative path logic. If the user-supplied string contains enough traversal sequences, the resulting path escapes the intended --out-dir boundary. The subsequent file writing operation then targets this escaped path location.
The remediation implemented in commit 84f3b450ce6e472c4abb8dc4c26d0ce8ac1259ac introduces explicit input validation. A new helper function, containsPathTraversal, was added to inspect strings for problematic character sequences.
// pkg/linter/results.go
// containsPathTraversal checks if a string contains path traversal sequences
// or path separators that could be used to escape the intended directory.
func containsPathTraversal(s string) bool {
return strings.Contains(s, "..") ||
strings.Contains(s, string(filepath.Separator)) ||
strings.Contains(s, "/")
}The saveLintResults function now invokes this validation against both the arch and pkgname variables. If either variable contains a traversal sequence, the operation halts and returns an error string, preventing any subsequent filesystem operations.
// Validate arch to prevent path traversal
if containsPathTraversal(arch) {
return fmt.Errorf("invalid arch %q: contains path traversal sequence", arch)
}
// Validate pkgName to prevent path traversal
if containsPathTraversal(pkgName) {
return fmt.Errorf("invalid package name %q: contains path traversal sequence", pkgName)
}This fix is robust as it comprehensively blocks the literal .. sequence as well as both common forward slash and OS-specific path separators. It operates on a deny-list principle for structural path characters, ensuring the metadata fields remain flat strings.
Exploitation requires the attacker to construct a malicious APK package with a crafted .PKGINFO file. The attacker modifies the arch or pkgname fields to include relative traversal sequences, such as ../../etc or ../../../tmp/payload.
The attacker then distributes this package to a target environment that processes untrusted APKs using melange. Common attack targets include automated CI/CD pipelines or security scanning infrastructure that lints third-party packages.
The target must execute the tool with the --persist-lint-results flag active. The requirement for this specific configuration limits the exposure surface for default deployments. Once triggered, the software evaluates the traversal sequence and writes the lint output to the specified location.
Successful exploitation results in an arbitrary file write primitive restricted to JSON content. The attacker can force the application to create directories outside the intended workspace and write a file with a .json extension based on the package versioning metadata.
This behavior allows for file clobbering, where existing JSON configuration files or reports on the target system are overwritten. The integrity impact is classified as low because the attacker cannot write arbitrary binary data, though they do control specific metadata fields within the injected JSON structure.
The CVSS v3.1 vector evaluates to CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L (Score 4.4). The attack requires local access to the processing pipeline and user interaction to initiate the linting process against the malicious payload. Confidentiality remains unaffected as no data is read back to the attacker.
Administrators must update melange to version 0.43.4 or later to eliminate this vulnerability. The updated version enforces structural integrity on the .PKGINFO fields and rejects anomalous input containing path separators.
If immediate patching is not feasible, operators should ensure the --persist-lint-results flag remains disabled when processing untrusted packages. This flag is disabled by default, meaning standard operations are not affected.
Running the melange process within an isolated container or using filesystem namespaces further restricts the potential write access of the process. Operators should also monitor build logs for "invalid arch" or "invalid package name" error messages as indicators of exploitation attempts.
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
melange chainguard-dev | >= 0.32.0, < 0.43.4 | 0.43.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Local (AV:L) |
| CVSS v3.1 | 4.4 (Medium) |
| Impact | Arbitrary JSON File Write / Clobbering |
| Exploit Status | Unexploited / No PoC |
| KEV Status | Not Listed |
The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.