Skip to content

CVE-2026-82331: Apache BuildStream Tar Plugin Link Resolution and Host File Overwrite

HERMES

HERMES THREAT SCORE & ENTERPRISE RISK EXPOSURE

Target: CI/CD Build Pipelines, Operating System Integration Stacks & Software Supply Chains
Confidence: 95%
91 / 100
CRITICAL

Measures real-world operational relevance, exploit weaponization, and active threat posture.

Dimension Breakdown
Exploitability 19 / 20
Threat Activity 16 / 20
Weaponization 18 / 20
Exposure 17 / 20
Prevalence 17 / 20
Impact 20 / 20
Exploit Maturity 18 / 20
Attack Chain Potential 19 / 20
⚖️ Divergence & Operational Rationale

CVSS v3.1 rates CVE-2026-82331 at 9.8 Critical (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H). Hermes Threat Score evaluates it at 91 (CRITICAL). BuildStream powers continuous integration and OS-level artifact builds for automotive, desktop, and embedded Linux distributions (including GNOME OS). In automated build systems and CI/CD runners, fetching untrusted or upstream tarballs is routine; symlink escape directly translates to build node takeover, toolchain backdoor injection, and supply chain contamination.

HASS

HASS AGENTIC SEVERITY & PERIMETER BOUNDARY IMPACT

Target: Apache BuildStream Tar Plugin Source Fetcher & Extraction Sandbox
Confidence: 90%
58 / 100
MODERATE

Measures specific systemic risk arising from autonomy, tool authority, and cascading execution.

Dimension Breakdown
Autonomy 14 / 20
Tool Access 15 / 20
Privilege 12 / 15
Persistence 9 / 15
External Impact 8 / 15
Propagation 0 / 15
⚖️ Divergence & Operational Rationale

Autonomous software development agents running build commands in development containers or runner sandboxes interact directly with build element manifests. An uncontained symlink breakout allows a maliciously crafted upstream tarball to escape the staging directory and compromise the agent's outer execution environment or persistent tool definitions.

🕸️ Connected Knowledge Graph & Provenance

CVE-2026-82331: Apache BuildStream Tar Plugin Link Resolution and Host File OverwriteVULNERABILITY

Connected Nodes: 3
Active Relationships (Outgoing)
→ affectsPRODUCTApache BuildStream
98% VERY_HIGH

Software platform affected by security vulnerabilities and agentic attack patterns.

🔍 Why is this related? (Evidence & Provenance)

“Confirmed security vulnerability in Apache BuildStream documented in Hermes dossier.”

Supporting Verified Evidence:
→ exploitsAGENTIC ATTACK_PATTERNAAP-007: Autonomous Cascading RCE
92% VERY_HIGH

Cascading multi-stage attack chaining context injection, autonomous loop planning, and un-sandboxed execution sinks to achieve persistent root shell compromise on host machines.

🔍 Why is this related? (Evidence & Provenance)

“CVE-2026-82331 weaponizes the agentic attack pattern formalized under AAP-007.”

Supporting Verified Evidence:
→ exploitsAGENTIC ATTACK_PATTERNAAP-003: Tool Parameter Tampering & Built-in Bypass
92% VERY_HIGH

Adversarial subversion of structured tool execution arguments (SQL, Shell, Filepath) passed from an LLM agent to host OS tools or MCP endpoints.

🔍 Why is this related? (Evidence & Provenance)

“CVE-2026-82331 weaponizes the agentic attack pattern formalized under AAP-003.”

Supporting Verified Evidence:

1. Technical Context & Affected Software Matrix

Section titled “1. Technical Context & Affected Software Matrix”

The tar source plugin is the default mechanism in BuildStream for tracking and staging compressed archives into isolated build staging sandboxes (Element.stage()).

ParameterTechnical SpecificationOperational Impact
CVE IdentifierCVE-2026-82331Apache Security Advisory / NIST NVD Entry
Vulnerability ClassLink Following (CWE-59) / Path Traversal (CWE-22)Arbitrary filesystem write outside build staging directory
Vulnerable Componentplugins/sources/tar.py (stage() extraction handler)Unvalidated archive extraction routine
Exploitation VectorCrafted tarball containing symlinks resolving outside target directoryOverwriting host configurations (~/.ssh, ~/.bashrc, /etc)
Privileges RequiredNone (PR:N)Triggered automatically during source fetching or building
Privileges ObtainedUser executing BuildStream (uid of build runner / CI worker)Persistent code execution on build nodes, pipeline manipulation
Affected VersionsApache BuildStream < 2.8.1 (on Python < 3.12)Linux OS integration pipelines, embedded build farms, CI workers
Fixed UpdatesApache BuildStream 2.8.1Path canonicalization checks and Python 3.12 data filter enforcement

2. Vulnerability Anatomy & Root Cause Analysis

Section titled “2. Vulnerability Anatomy & Root Cause Analysis”
Section titled “Unchecked Symlink Dereferencing in tarfile Extraction”

When BuildStream stages a tar source element into a sandbox directory, it historically relied on Python’s built-in tarfile module. Prior to Python 3.12 (which introduced PEP 706 data filter support), tarfile.extractall() inherently followed symlinks created earlier in the same archive without checking whether the destination directory remained inside the destination path:

# Vulnerable archive extraction logic in BuildStream tar plugin (pre-2.8.1)
def stage(self, directory: str) -> None:
# directory represents the intended sandbox root (e.g. /tmp/buildstream-staging-xyz)
archive_path = self._get_mirror_file()
with tarfile.open(archive_path, mode="r:*") as tar:
# FLAW: On Python < 3.12 without manual link checking, tar.extractall()
# unpacks members sequentially without verifying destination realpaths
for member in tar.getmembers():
# If member is a symlink pointing to "/", or "../../../home/user",
# it is created on disk at directory/symlink_name.
# When a subsequent member "symlink_name/evil_file" is extracted,
# tarfile writes through the symlink directly onto the host filesystem!
tar.extract(member, path=directory)

Exploitation Mechanics: The Two-Stage Tarball

Section titled “Exploitation Mechanics: The Two-Stage Tarball”

An attacker crafts a malicious tarball containing two entries:

  1. Stage 1 (Symlink Trap): A symbolic link named escape_link pointing to /home/builder/.ssh.
  2. Stage 2 (Payload File): A file named escape_link/authorized_keys containing the attacker’s public SSH key.

During extraction, escape_link is created inside the staging directory. When the extractor encounters escape_link/authorized_keys, Python’s underlying OS open() call dereferences the symlink, writing the public key directly into /home/builder/.ssh/authorized_keys on the build runner host.


3. Attack Vectors & Forensic Execution Flow

Section titled “3. Attack Vectors & Forensic Execution Flow”
sequenceDiagram
autonumber
actor Attacker as Upstream Attacker / Contributor
participant Git as Upstream Git / Source Mirror
participant CI as CI/CD Runner / BuildStream
participant Plugin as BuildStream tar Plugin
participant HostFS as Host Filesystem (~/builder)
Attacker->>Git: Submit PR with upstream tarball containing symlink trap
Git->>CI: Trigger automated build pipeline via .bst manifest
CI->>Plugin: Invoke tar plugin stage() to extract source archive
Plugin->>HostFS: Extract entry 1: symlink "link" -> "~/.ssh"
Plugin->>HostFS: Extract entry 2: file "link/authorized_keys" (attacker pubkey)
Note over HostFS: Symlink dereferenced! Authorized keys overwritten on host
CI-->>Attacker: Build finishes or errors out
Attacker->>CI: Connect via SSH using overwritten credentials (full access)
Attacker->>CI: Backdoor compiler binaries / inject malicious firmware payloads
  1. Malicious Tarball Creation: The attacker crafts an archive with a symlink targeting sensitive host configuration paths (~/.ssh, ~/.bashrc, or /etc/cron.d) followed by a payload file whose path traverses through the symlink.
  2. Manifest Submission: The adversary commits or submits a pull request updating an element’s url or source reference in a .bst file to point to the crafted tarball.
  3. Build Execution: An automated CI runner or developer executes bst build target.bst. BuildStream fetches the archive and invokes stage() to populate the build sandbox.
  4. Symlink Traversal & Host Write: The unpatched tar plugin extracts the symlink and sequentially writes the payload file through the link, overwriting the target file on the host.
  5. Persistence & Pipeline Poisoning: The attacker leverages the overwritten SSH keys or shell startup files to establish a foothold on the build server, compromising subsequent software releases.

4. Forensic Investigation & Incident Response

Section titled “4. Forensic Investigation & Incident Response”

DFIR teams investigating suspicious BuildStream CI runners should conduct the following checks:

Host Triage & Integrity Verification Commands

Section titled “Host Triage & Integrity Verification Commands”
Terminal window
# 1. Audit user SSH keys for unauthorized modifications
stat ~/.ssh/authorized_keys
tail -n 20 ~/.ssh/authorized_keys
# 2. Check for unexpected symlinks in BuildStream storage directories
find ~/.cache/buildstream/ -type l -ls
# 3. Inspect recent shell startup files and crontabs for newly added entries
stat ~/.bashrc ~/.profile /etc/cron* -c "%y %n" | sort -r | head -n 20
# 4. Review active processes and established connections on the CI runner
ss -tulpn
pstree -a $(pgrep -f "bst")
# 5. Search for newly modified binaries in standard toolchain paths
find /usr/local/bin /opt -mtime -3 -type f -ls

title: File Modification via Build Tool Symlink Traversal
id: 82331c01-buildstream-tar-symlink
status: experimental
description: Detects unauthorized writes to user SSH keys or system configuration paths spawned by build runner processes.
author: Hermes Codex Detection Engineering
date: 2026-09-24
logsource:
category: file_event
product: linux
detection:
selection_process:
Image|endswith:
- '/bst'
- '/python3'
- '/python'
selection_target:
TargetFilename|contains:
- '/.ssh/'
- '/.bashrc'
- '/etc/cron'
- '/etc/sudoers'
condition: selection_process and selection_target
falsepositives:
- Administrative setup scripts configuring CI runner identities.
level: critical
tags:
- attack.initial_access
- attack.t1195.001
- cve.2026-82331

Update all build runners, workstations, and CI agents to Apache BuildStream 2.8.1 or higher:

Terminal window
pip install --upgrade buildstream>=2.8.1
  1. Migrate to Python 3.12+: Ensure the Python environment hosting BuildStream is Python 3.12 or later, which enforces PEP 706 tarfile.data_filter by default.
  2. Rootless & Ephemeral CI Runners: Run all build jobs inside ephemeral, non-root containers (runAsNonRoot: true) with no shared volumes mounted to host identity directories (~/.ssh, host docker sockets).
  3. Immutable Source Artifacts: Enforce cryptographic SHA-256 hash pinning for all external tarballs in .bst element declarations.

7. Correlated Research & Internal References

Section titled “7. Correlated Research & Internal References”