GNU Guix 'guix substitute' and 'guix pull' Vulnerabilities Enable Arbitrary File Write, Metadata Spoofing, Local Secret Disclosure, and Path Traversal (CVE Pending)

GNU Guix 'guix substitute' and 'guix pull' Vulnerabilities (TL-2026-1179) is a high-severity software vulnerability, first published 2026-07-10. It has no confirmed attribution, affects GNU Project GNU Guix (guix-daemon / guix client, 'guix substitute'), maps to 21 MITRE ATT&CK techniques (T1005, T1036.008, T1068), and is covered by 9 detection rules and 25 indicators of compromise.

Key facts for TL-2026-1179

Threat ID
TL-2026-1179
Severity
HIGH
Status
PATCHED
Category
VULNERABILITY
First published
2026-07-10
Last reviewed
2026-07-10
Attribution confidence
LOW
Motivation
UNKNOWN
Target sectors
software-development, research, academia, open-source-infrastructure, technology
Target regions
Global
Detection rules
9
Indicators of compromise
25

GNU Guix disclosed four security flaws on 2026-07-02: three in 'guix substitute' — a race between archive extraction and hash verification in restore-file enabling arbitrary file write (up to /etc/passwd when guix-daemon runs as root), a missing narinfo request/response binding check in fetch-narinfos allowing substitution of unintended authorized store items, and unsafe file:// URI handling that can leak local secrets via error backtraces — plus a path-traversal flaw in guix pull / guix time-machine's authenticate-channel cache-key derivation enabling denial-of-service file overwrites. No CVE IDs were assigned at disclosure time. Fixed via 11 commits merged as pull request #9665 (codeberg.org/guix/guix), final commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c.

How GNU Guix 'guix substitute' and 'guix pull' Vulnerabilities works

On 2026-07-02, the GNU Guix security team published an advisory disclosing four distinct vulnerabilities affecting the 'guix substitute' helper (invoked by guix-daemon to download pre-built binary substitutes) and the 'guix pull'/'guix time-machine' channel-authentication caching logic. Guix is a functional, transactional package manager and the basis of the GNU Guix System distribution, widely used in reproducible-build and NixOS-adjacent communities.

Vulnerability 1 (primary/most severe) — the restore-file procedure in the (guix serialization) module, responsible for unpacking NAR (Nix ARchive) substitute archives, was invoked to extract archive contents as they streamed in from the network, before the complete archive's cryptographic hash could be verified against the signed narinfo metadata. restore-file additionally did not validate directory entry names for path traversal characters ('/'), null bytes, or duplicate/out-of-order entries. Because extraction happened before verification, and because entry names were unvalidated, any substitute server the client is configured to trust — or any network attacker able to impersonate one (MITM) — could serve a crafted NAR archive that wrote attacker-chosen file contents to attacker-chosen paths writable by the guix-daemon user. Since guix-daemon commonly runs as root for system-wide installs, this allowed remote overwrite of files such as /etc/passwd, i.e. remote privilege escalation to full root compromise, plus general Guix store corruption. Notably, the researcher (Jörg Thalheim, known for Nix ecosystem security work) demonstrated that even though NARs are cryptographically signed, streaming extraction before verification defeated that protection — the signature check happened too late to prevent the malicious write.

Vulnerability 2 — fetch-narinfos in guix/substitutes.scm did not verify that a narinfo returned by a substitute server actually corresponded to the store item that was requested. A malicious or compromised substitute server could return the (validly signed, 'authorized') narinfo for a different but also-authorized store item than the one requested. This allowed forced substitution of one authorized package for another authorized package, enabling downgrade-style attacks: a target system could be made to install an older, vulnerable, but still-signed version of a package instead of the one actually referenced by name/hash, silently defeating version pinning.

Vulnerability 3 — guix substitute accepted file:// URIs both as substitute-server URLs and as nar URLs embedded within narinfo responses, and followed symbolic links when resolving them. A local, unprivileged user able to connect to the guix-daemon Unix socket (the default local trust boundary) could supply crafted narinfo/URL input that caused parsing errors; the resulting error backtraces could include the contents of arbitrary files readable by the daemon user, disclosing secrets, credentials, or configuration data. The advisory also notes potential for interference with other processes via /proc/PID/fd symlink manipulation.

Vulnerability 4 — authenticate-channel in (guix channels), used by guix pull and guix time-machine to authenticate a channel's Git commit history, derived a local cache file name directly from the (attacker-influenceable) channel name without sanitization. A malicious or spoofed channels file containing a crafted channel name (e.g. containing '../../../../newfile' style traversal sequences) could cause Guix to create or overwrite files outside the intended cache directory, anywhere the invoking user can write. Primary impact is denial-of-service via unwanted file creation/overwrite; the advisory notes more creative escalation may be possible via /proc special files.

All four issues were fixed in a coordinated series of 11 commits merged 2026-07-02 (final commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c) as pull request/patchset #9665 on the project's Codeberg mirror, authored primarily by Ludovic Courtès (civodul) and collaborators. Fixes include: strict directory-entry-name validation and O_EXCL/O_NOFOLLOW-guarded extraction to a temporary location prior to hash verification in restore-file (commit c7e4429); request/response narinfo matching checks in fetch-narinfos and cached-narinfo (commit 797ec01); new %allow-unsafe-substitute-uris?/%allow-unsafe-narinfo-uris? parameters and uri-safe?/narinfo-uris-safe? validators that reject untrusted file:// URIs (commit c5fdcf7); and cache-key derivation for channel authentication changed from raw channel name to the channel's introductory commit ID with dot-to-dash sanitization, removing attacker control of the cache path (commit bfb3031). A defense-in-depth hardening of the C++ daemon-side NAR parser (nix/libutil/archive.cc) adding a DIRECTORY_NESTING_LIMIT of 256 and stricter structural validation was also merged (commit e95120), along with new valid-store-name?/valid-path-syntax? helpers (commit e27a82). No CVE identifiers had been assigned as of the 2026-07-02 advisory / 2026-07-10 secondary reporting. Disclosure timeline: Jörg Thalheim privately reported the restore-file issue on 2026-05-28; the Guix security team discovered and developed fixes for the remaining three issues between 2026-06-04 and 2026-06-24; the coordinated advisory and patch went public 2026-07-02.

MITRE ATT&CK techniques used in TL-2026-1179

Collection

T1005 Data from Local System; T1213 Data from Information Repositories

Defense Evasion

T1036.008 Masquerade File Type; T1211 Exploitation for Stealth

Privilege Escalation

T1068 Exploitation for Privilege Escalation

Discovery

T1083 File and Directory Discovery; T1518 Software Discovery

Command and Control

T1132 Data Encoding

Credential Access

T1187 Forced Authentication; T1552.001 Credentials In Files

Initial Access

T1190 Exploit Public-Facing Application; T1195 Supply Chain Compromise

initial-access

T1195.002 Compromise Software Supply Chain

Execution

T1203 Exploitation for Client Execution

defense-impairment

T1222 File and Directory Permissions Modification

Impact

T1499 Endpoint Denial of Service; T1531 Account Access Removal; T1565.001 Stored Data Manipulation

Persistence

T1505 Server Software Component

credential-access

T1557 Adversary-in-the-Middle

stealth

T1574.009 Path Interception by Unquoted Path

Affected products and versions in GNU Guix 'guix substitute' and 'guix pull' Vulnerabilities

  • GNU Project — GNU Guix (guix-daemon / guix client, 'guix substitute')
    Vulnerable versions: all versions prior to commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c
    Fixed in: commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c and later
  • GNU Project — GNU Guix ('guix pull' / 'guix time-machine' channel authentication)
    Vulnerable versions: all versions prior to commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c
    Fixed in: commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c and later
  • GNU Project — GNU Guix System (distributions relying on guix-daemon running as root)
    Vulnerable versions: all Guix System installations prior to the fix
    Fixed in: reconfigured with guix-daemon rebuilt from commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c or later

Remediation for GNU Guix 'guix substitute' and 'guix pull' Vulnerabilities

Patches

  • Pull request #9665 on codeberg.org/guix/guix — 11 commits merged 2026-07-02, final commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c

Immediate actions

  • Upgrade guix and guix-daemon to commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c or later immediately
  • On Guix System: run 'guix pull' then 'sudo guix system reconfigure <config>' and restart guix-daemon
  • On foreign distributions: run 'sudo --login guix pull' then 'sudo systemctl restart guix-daemon.service'
  • Pass --no-substitutes to all 'guix' commands while upgrading to eliminate remote substitute-server attack surface during the exposure window
  • Run the project-supplied validation script (guix-substitute-and-pull-vuln-check.scm) to confirm all four protections are active (expect exit code 0)

Workarounds

  • Use --no-substitutes to disable remote substitute fetching entirely until upgraded
  • Disable or restrict guix pull / guix time-machine usage with untrusted channel files until upgraded

Longer-term hardening

  • Restrict which substitute servers are configured/trusted (avoid arbitrary/unauthenticated substitute-server URLs)
  • Run guix-daemon as a non-root dedicated build user wherever the deployment model allows it, to bound the impact of any future extraction-time file-write bug
  • Restrict local access to the guix-daemon Unix socket to trusted users only, to mitigate the file:// disclosure vector
  • Vet and pin channels.scm entries from trusted sources only; avoid consuming third-party channel definitions without review

Weaknesses (CWE) in GNU Guix 'guix substitute' and 'guix pull' Vulnerabilities

CWE-22, CWE-345, CWE-367, CWE-209, CWE-611, CWE-732

Timeline of GNU Guix 'guix substitute' and 'guix pull' Vulnerabilities

  • Jörg Thalheim (Nix ecosystem security researcher) privately discloses the restore-file arbitrary-file-write vulnerability in 'guix substitute' to Guix maintainers Christopher Baines and Andreas Enge, who forward details to the Guix Security Response Team.
  • Andreas Enge notifies Caleb Ristvedt and Ludovic Courtès of the restore-file report, initiating a broader collaborative review of the substitute and channel-authentication code paths.
  • Caleb Ristvedt independently identifies the file:// URI / symlink-following local information-disclosure vulnerability (Vulnerability 3) in 'guix substitute' during the code review.
  • Caleb Ristvedt discovers that 'guix substitute' does not verify that a returned narinfo corresponds to the store item actually requested, identifying the narinfo request/response binding vulnerability (Vulnerability 2).
  • Following an issue report by Sergio Pastor-Pérez, Ludovic Courtès identifies the path-traversal vulnerability in 'guix pull' / 'guix time-machine' channel-authentication cache-key derivation (Vulnerability 4), completing identification of all four issues ahead of coordinated fix development.
  • GNU Guix project publishes official advisory 'guix substitute and guix pull Vulnerabilities' on guix.gnu.org detailing all four flaws, remediation steps, and the guix-substitute-and-pull-vuln-check.scm validation script.
  • Pull request #9665 (11 commits, first ed0a9721f8a20d6ddcf6a0495302f502b3f7bb17, last 2ef8ed9f0df53bddf14bdecc2ea48c2d233213cc) merged by Ludovic Courtès (civodul) on codeberg.org/guix/guix; final fixed commit is 897832f374dcdc9eeaf19d01e70b9a92fccfc68c.
  • Secondary technical coverage published by LWN.net ('Four vulnerabilities in Guix'), Linuxiac, Cyberpress, and Linux Consultant, summarizing the advisory for a broader audience; community members report upgrade complications requiring the --no-offload flag on some systems.
  • GNU Guix Blog issues an update to the advisory addressing a regression in the deployed fix that affected normal substitute functionality for some users.
  • cybersecuritynews.com publishes coverage of the disclosure, which serves as the hunt source for this threat record; CVE identifiers remain unassigned/pending at time of reporting.

Sources cited for GNU Guix 'guix substitute' and 'guix pull' Vulnerabilities

Threats related to GNU Guix 'guix substitute' and 'guix pull' Vulnerabilities

Detection coverage for TL-2026-1179

As of 2026-07-10, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-1179 across Splunk SPL, Microsoft KQL and Sigma, covering 25 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Latest Threats