diffoscope writes to arbitrary locations on disk based on the contents of an untrusted archive
Description
diffoscope before 77 writes to arbitrary locations on disk based on the contents of an untrusted archive.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
diffoscope before version 77 writes to arbitrary disk locations based on untrusted archive contents, enabling arbitrary file write.
Vulnerability
diffoscope before version 77 [1][2] writes to arbitrary locations on disk based on the contents of an untrusted archive. The vulnerability is present in the way diffoscope unpacks and processes archives to compare file differences. Affected versions are all releases prior to 77, with the fix introduced in version 77 by commit f379d1f [3]. No special configuration is required for the code path to be reachable; simply processing a malicious archive triggers the issue.
Exploitation
An attacker needs to supply a crafted archive to a user running diffoscope. No authentication or special network position is required beyond delivering the archive to the victim (e.g., via email, a download, or a repository). The vulnerable code follows archive paths from the untrusted content and writes extracted data to arbitrary locations, without proper validation or sanitization [1][4].
Impact
On successful exploitation, an attacker can write files to arbitrary locations on the filesystem with the privileges of the user running diffoscope [1][4]. This can lead to overwriting critical system files, planting configuration files, or achieving code execution depending on the write target. The impact includes both integrity and availability compromise, and potentially escalation to remote code execution.
Mitigation
Upgrade to diffoscope version 77 or later, which was released with the fix [3]. Users on Debian-based systems should apply the package update from the Debian repository [4]. There is no known workaround for earlier versions; users must update to a patched version. This CVE is not listed in the KEV catalog.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
diffoscopePyPI | < 76 | 76 |
Affected products
3- ghsa-coords2 versions
< 76+ 1 more
- (no CPE)range: < 76
- (no CPE)range: < 183-1.2
- Debian/diffoscopev5Range: before 77
Patches
2f379d1f611dbAdd CVE-2017-0359 to the changelog of v76
1 file changed · +1 −1
debian/changelog+1 −1 modified@@ -3,7 +3,7 @@ diffoscope (76) unstable; urgency=medium [ Chris Lamb ] * Extract archive members using an auto-incrementing integer, avoiding the need to sanitise filenames and avoiding writes to arbitrary locations. - (Closes: #854723) + (Closes: #854723 - CVE-2017-0359) [ Ximin Luo ] * Simplify call to subprocess.Popen
632a40828a54Extract archive members using an auto-incrementing integer, avoiding the need to sanitise filenames. (Closes: #854723)
1 file changed · +14 −27
diffoscope/comparators/utils/libarchive.py+14 −27 modified@@ -23,6 +23,7 @@ import ctypes import logging import libarchive +import collections from diffoscope.tempfiles import get_temporary_directory @@ -168,11 +169,11 @@ def close_archive(self): def get_member_names(self): self.ensure_unpacked() - return self._member_names + return self._members.keys() def extract(self, member_name, dest_dir): self.ensure_unpacked() - return os.path.join(self._unpacked, member_name) + return self._members[member_name] def get_member(self, member_name): with libarchive.file_reader(self.source.path) as archive: @@ -197,45 +198,31 @@ def get_subclass(self, entry): return LibarchiveMember(self, entry) def ensure_unpacked(self): - if hasattr(self, '_unpacked'): + if hasattr(self, '_members'): return - self._unpacked = get_temporary_directory().name - self._member_names = [] + tmpdir = get_temporary_directory().name + self._members = collections.OrderedDict() - logger.debug("Extracting %s to %s", self.source.path, self._unpacked) + logger.debug("Extracting %s to %s", self.source.path, tmpdir) with libarchive.file_reader(self.source.path) as archive: - for entry in archive: - self._member_names.append(entry.pathname) + for idx, entry in enumerate(archive): + # Maintain a mapping of archive path to the extracted path, + # avoiding the need to sanitise filenames. + dst = os.path.join(tmpdir, '{}'.format(idx)) + self._members[entry.pathname] = dst if entry.isdir: continue - # All extracted locations must be underneath self._unpacked - force_prefix = os.path.join(self._unpacked, "") - - # Try to pick a safe and reasonable candidate name - candidate_name = os.path.normpath(entry.pathname.rstrip('/' + os.sep)) - if os.path.isabs(candidate_name): - candidate_name = os.path.relpath(candidate_name, os.path.join(os.path.sep)) - - dst = os.path.normpath(os.path.join(self._unpacked, candidate_name)) - if not dst.startswith(force_prefix): - logger.warn("Skipping member because we could not make a safe name to extract it to: '%s'", - entry.pathname) - continue - - # TODO: need to fix reading these cleaned members. currently - # reading will still try to use the uncleaned name. - #logging.debug("Extracting %s to %s", entry.pathname, dst) - os.makedirs(os.path.dirname(dst), exist_ok=True) + logger.debug("Extracting %s to %s", entry.pathname, dst) with open(dst, 'wb') as f: for block in entry.get_blocks(): f.write(block) logger.debug( "Extracted %d entries from %s to %s", - len(self._member_names), self.source.path, self._unpacked, + len(self._members), self.source.path, tmpdir, )
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-8p5c-f328-9fvvghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-0359ghsaADVISORY
- bugs.debian.org/854723ghsax_refsource_CONFIRMWEB
- bugs.debian.org/cgi-bin/bugreport.cgighsaWEB
- github.com/anthraxx/diffoscope/commit/632a40828a54b399787c25e7fa243f732aef7e05ghsaWEB
- github.com/anthraxx/diffoscope/commit/f379d1f611dbd5d361e12b732e07c8aee45ff226ghsaWEB
- github.com/pypa/advisory-database/tree/main/vulns/diffoscope/PYSEC-2018-83.yamlghsaWEB
- security-tracker.debian.org/tracker/CVE-2017-0359ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.