CVE-2026-15331 Overview
CVE-2026-15331 is a path traversal vulnerability [CWE-22] affecting zhayujie CowAgent versions up to 2.1.0. The flaw resides in the _add_url and _add_package functions within agent/skills/service.py, part of the Skill Installation Handler component. An authenticated remote attacker can manipulate the Name argument to escape the intended skills directory and write files to arbitrary locations on the host filesystem. The maintainers addressed the issue in version 2.1.2 via commit e85290cddcbb5ffc9c235927f4c92e5b4c3ec264.
Critical Impact
Remote authenticated attackers can traverse outside the skills directory during skill installation, enabling arbitrary file placement that may lead to code execution or configuration tampering.
Affected Products
- zhayujie CowAgent versions up to and including 2.1.0
- Component: Skill Installation Handler (agent/skills/service.py)
- Fixed release: CowAgent 2.1.2
Discovery Timeline
- 2026-07-10 - CVE-2026-15331 published to NVD
- 2026-07-10 - Last updated in NVD database
Technical Details for CVE-2026-15331
Vulnerability Analysis
The vulnerability stems from improper validation of the user-supplied Name parameter passed into the skill installation routines. Both _add_url and _add_package in agent/skills/service.py construct a filesystem path by joining self.manager.custom_dir with the attacker-controlled name. Without normalization or containment checks, values such as ../ sequences or absolute paths resolve outside the designated skills root. This grants the attacker write access to arbitrary directories reachable by the CowAgent process.
Because the affected functions execute during skill installation, exploitation is possible over the network with low-privilege credentials. The EPSS score is 0.378% (30th percentile), indicating limited observed exploitation activity at publication.
Root Cause
The root cause is missing path canonicalization and containment enforcement [CWE-22]. The pre-patch code passed the name argument directly into os.path.join without rejecting traversal sequences or verifying the resolved path against the skills root directory.
Attack Vector
An authenticated remote attacker submits a crafted skill installation request with a Name value containing directory traversal payloads such as ../../etc/cowagent or an absolute path like /tmp/malicious. The Skill Installation Handler resolves the path and writes attacker-controlled files outside the intended custom_dir, potentially overwriting configuration files or dropping payloads into locations processed by other services.
# Patch applied in agent/skills/service.py (CVE-2026-15331 fix)
def _safe_skill_dir(self, name: str) -> str:
"""Derive and validate the skill directory path.
Ensures the resolved path stays within the custom_dir root,
preventing path traversal via names like ``../escaped``.
:raises ValueError: if the name would escape the skills root.
"""
if not name or not name.strip():
raise ValueError("skill name is required")
# Reject obvious traversal components.
if ".." in name or name.startswith("/") or name.startswith("\\"):
raise ValueError(f"invalid skill name (path traversal detected): {name!r}")
skill_dir = os.path.realpath(os.path.join(self.manager.custom_dir, name))
root = os.path.realpath(self.manager.custom_dir)
if not skill_dir.startswith(root + os.sep) and skill_dir != root:
raise ValueError(
f"skill name {name!r} resolves outside the skills directory"
)
return skill_dir
Source: GitHub Commit e85290c
Detection Methods for CVE-2026-15331
Indicators of Compromise
- Unexpected files or directories created outside the CowAgent custom_dir skills root by the CowAgent process user.
- Skill installation requests where the Name parameter contains .., forward slashes, backslashes, or absolute path prefixes.
- Application logs showing skill installations that reference non-standard or system paths.
Detection Strategies
- Inspect HTTP request bodies to the skill installation endpoints for traversal patterns in the Name field.
- Enable Python-level auditing or filesystem auditing on the CowAgent working directory to flag writes outside custom_dir.
- Compare running CowAgent version against the fixed release 2.1.2 and flag any deployment at or below 2.1.0.
Monitoring Recommendations
- Monitor file creation events under sensitive directories (/etc, /root, home directories) originating from the CowAgent service account.
- Alert on repeated ValueError exceptions from _safe_skill_dir after patching, which indicate active exploitation attempts.
- Aggregate CowAgent access logs into a central log platform and hunt for anomalous Name values during skill installation.
How to Mitigate CVE-2026-15331
Immediate Actions Required
- Upgrade zhayujie CowAgent to version 2.1.2 or later, which includes the _safe_skill_dir containment check.
- Restrict network access to the CowAgent skill installation endpoints to trusted administrative users only.
- Audit the CowAgent host for files written outside the expected custom_dir since deployment.
Patch Information
The fix is delivered in commit e85290cddcbb5ffc9c235927f4c92e5b4c3ec264 and released as CowAgent 2.1.2. See the GitHub Release 2.1.2, the GitHub Pull Request, and the GitHub Issue Report for complete remediation context.
Workarounds
- If immediate upgrade is not feasible, disable the skill installation feature or block access to the affected endpoints at the reverse proxy.
- Run CowAgent under a dedicated low-privilege user with a restrictive filesystem policy (for example, AppArmor or SELinux) that confines writes to the skills directory.
- Apply an input validation shim in front of CowAgent that rejects any Name value containing .., /, or \.
# Example: verify installed CowAgent version and upgrade
pip show cowagent | grep -i version
pip install --upgrade "cowagent>=2.1.2"
# Example: AppArmor-style restriction (illustrative)
# deny write access outside the skills custom_dir
deny /** w,
allow /opt/cowagent/skills/** rw,
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

