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-27485
4.6

OpenClaw's Sticky Paws: Symlink Following & Zip Slip (CVE-2026-27485)

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 21, 2026·5 min read·6 visits

PoC Available

Executive Summary (TL;DR)

OpenClaw's skill packager followed symlinks by default. If you packaged a folder with a link to /etc/passwd, you unknowingly mailed your password hashes to the internet. Fixed in 2026.2.18.

A classic UNIX nuance bites a modern AI tool. OpenClaw, the open-source personal AI assistant, contained a vulnerability in its skill packaging utility that allowed for arbitrary file read via symbolic link following. By crafting a malicious skill directory containing symlinks to sensitive files (like SSH keys or password databases), an attacker could trick a developer or user into packaging those external files into a distributable archive. Additionally, a secondary path traversal (Zip Slip) vulnerability was identified in the same component, allowing for potential file overwrites during extraction.

The Hook: The AI That Knew Too Much

We all love personal AI assistants. They organize our calendars, tell us the weather, and—in the case of OpenClaw—accidentally bundle up our private SSH keys and ship them off to the internet. OpenClaw relies on a plugin system called "Skills." Users and developers create these skills in local directories and then use a helper script, package_skill.py, to zip them up for distribution. It sounds mundane, right? It's just a zipper.

But here is the thing about "mundane" utility scripts: they are often written with the assumption that the user is a benevolent operator working in a sterile environment. They rarely account for the fact that the directory being zipped might be a minefield laid by an attacker, or that the user might be accidentally pointing the gun at their own foot.

CVE-2026-27485 is a story about the difference between "files" and "paths," and what happens when Python's standard libraries do exactly what they are told to do, rather than what they should do. It turns a simple packaging utility into an unintentional data exfiltration tool.

The Flaw: A fatal game of 'Go Fetch'

The vulnerability lies in how UNIX filesystems handle symbolic links (symlinks) and how the Python zipfile library interacts with them. A symlink is essentially a signpost that says, "The data you are looking for is actually over there."

When you ask a standard archiving tool to zip up a directory, you have a choice: do you archive the signpost (the link itself), or do you follow the signpost and archive the destination?

By default, zipfile.ZipFile.write() is somewhat agnostic, but when combined with pathlib.Path.rglob("*") (which OpenClaw was using to find files), the script blindly grabbed every entry in the directory. When write() encounters a path, it resolves it. If that path is a symlink pointing to /home/user/.ssh/id_rsa, the script dutifully reads the private key and stuffs it into the archive under the filename id_rsa.

> [!NOTE] > This is not a memory corruption bug. It is a logic flaw. The code failed to ask the critical question: "Is this file actually inside the directory I am supposed to be packaging?"

To make matters worse, the developers also missed a secondary vulnerability: Zip Slip. The script accepted file paths without sanitizing them for directory traversal characters (../). This means not only could it suck data out (via symlinks), but a malicious archive could also write data over sensitive files on the victim's machine during extraction.

The Code: The Smoking Gun

Let's look at the vulnerable code in skills/skill-creator/scripts/package_skill.py. It's a classic example of naive iteration.

The Vulnerable Code

# Before the fix
with zipfile.ZipFile(output_filename, 'w') as zipf:
    # Recursively find all files
    for file_path in skill_dir.rglob("*"):
        # Calculate the relative path inside the zip
        arcname = file_path.relative_to(skill_dir)
        
        # WRITE IT ALL! No checks, no fear.
        zipf.write(file_path, arcname)

The fix, applied in commit c275932aa4230fb7a8212fe1b9d2a18424874b3f, introduces a sanity check. It explicitly asks if the file is a symlink and rejects it if so. It also checks for the Zip Slip traversal pattern.

The Fix

# After the fix
for file_path in skill_dir.rglob("*"):
    arcname = file_path.relative_to(skill_dir)
 
    # 1. The Symlink Check
    if file_path.is_symlink():
        print(f"[ERROR] Symlinks are not allowed in skills: {file_path}")
        return None
 
    # 2. The Zip Slip Check
    if ".." in arcname.parts or arcname.is_absolute():
        print(f"[ERROR] Invalid path in skill: {arcname}")
        return None
        
    zipf.write(file_path, arcname)

While this patches the immediate CVE, seasoned attackers might notice something interesting: is_symlink() only checks for symbolic links. It does not check for hard links. If an attacker can create a hard link on the same filesystem, this check is bypassed entirely.

The Exploit: Trojan Horse Skills

Exploiting this requires social engineering or a supply chain attack context. We want to trick a developer into packaging a skill that contains a "trap."

Attack Scenario

  1. The Setup: The attacker creates a legitimate-looking OpenClaw skill repository on GitHub.
  2. The Trap: Inside the assets/ folder of the skill, the attacker creates a symbolic link named config_backup.json that points to /etc/passwd or ~/.aws/credentials.
    ln -s /home/victim/.aws/credentials my_skill/assets/defaults.json
  3. The Bait: The attacker convinces a victim (perhaps a maintainer or a user forking the repo) to run package_skill.py to build the skill for their own use.
  4. The Execution:
    • The victim runs: python package_skill.py my_skill
    • The script sees assets/defaults.json.
    • It resolves the link to ~/.aws/credentials.
    • It reads the AWS keys.
    • It writes them into my_skill.zip.
  5. The Exfiltration: The victim unknowingly uploads the generated my_skill.zip to a public forum, Discord, or repository release page, effectively publishing their AWS credentials to the world.

This is particularly dangerous in CI/CD environments. If a CI pipeline automatically packages skills found in a repo, a pull request adding a symlink could cause the CI runner to leak its own secrets into the build artifacts.

Mitigation & Bypasses

The primary mitigation is updating to OpenClaw version 2026.2.18 or 2026.2.19. These versions include the logic to reject symlinks and path traversal attempts.

The Hard Link Bypass

As noted in the code analysis, the fix relies on file_path.is_symlink().

> [!WARNING] > Researcher Note: This patch is incomplete regarding Hard Links.

If the attacker has local access (or if the repo is checked out on a filesystem that supports hard links), they can use ln target link_name (without -s).

Hard links share the same inode as the original file. To Python's pathlib, a hard link looks exactly like a regular file. is_symlink() returns False. The zipfile library will happily read the content. However, hard links cannot cross filesystem boundaries (partitions), which limits the attack surface significantly compared to symlinks, which can point anywhere.

Official Patches

OpenClawPrimary Fix Commit

Fix Analysis (2)

Technical Appendix

CVSS Score
4.6/ 10
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N

Affected Systems

OpenClaw Personal AI Assistant (<= 2026.2.17)Custom scripts utilizing package_skill.py

Affected Versions Detail

Product
Affected Versions
Fixed Version
OpenClaw
OpenClaw
<= 2026.2.172026.2.18
AttributeDetail
CWE IDCWE-61 (Symlink Following)
Secondary CWECWE-22 (Path Traversal / Zip Slip)
CVSS v4.04.6 (Medium)
Attack VectorLocal / User Interaction Required
ImpactInformation Disclosure (High Confidentiality Risk)
Patch StatusFixed in 2026.2.18

MITRE ATT&CK Mapping

T1559Inter-Process Communication
Execution
T1005Data from Local System
Collection
T1204User Execution
Execution
CWE-61
Unix Symbolic Link (Symlink) Following

The software does not properly resolve or reject symbolic links, allowing access to files outside the intended directory.

Known Exploits & Detection

Internal ResearchProof of concept involves creating a symlink to sensitive files within a skill package source.

Vulnerability Timeline

Vulnerability Reported (OC-22)
2026-02-19
Patch Developed & Pushed
2026-02-19
OpenClaw 2026.2.18 Released
2026-02-19
CVE-2026-27485 Published
2026-02-21

References & Sources

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

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.