Back to skill

Security audit

Yufluent Clawhub Publish Yufluentcn Inventory Pilot

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent cloud inventory-analysis client, but it uploads local file contents and API credentials through under-scoped network and file-handling paths that users should review before installing.

Install only if you are comfortable sending selected sales, stock, inventory-aging, lead-time, and cost data to Yufluent/OpenClaw cloud services. Use explicit, non-sensitive input files, avoid passing arbitrary local paths, keep TOKENAPI_BASE_URL unset unless you trust the endpoint, and do not use non-local HTTP endpoints with a real TOKENAPI_KEY.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/cloud_cli.py:12
Finding

Unrestricted Local File Reading and Transmission to a Network Service

Content
View full analysis
str: """CLI argument: read an existing file path, or otherwise treat it as raw text.""" raw = (value or "").strip() if not raw: return "" path = Path(raw) if path.is_file(): return path.read_text(encoding="utf-8") return raw ``` The resulting file content is added directly to the request payload: ```python if args.sales_data: payload["sales_data"] = read_text_arg(args.sales_data) if args.current_stock: payload["current_stock"] = read_text_arg(args.current_stock) if args.inventory_data: payload["inventory_data"] = read_text_arg(args.inventory_data) ``` The complete payload is then transmitted: ```python root = base_url or os.getenv("TOKENAPI_BASE_URL", "") url = skill_run_url(root, skill_id) try: resp = _post_json(url, api_key=key, body=payload, timeout=timeout) ``` ### Technical Analysis The file-argument helper interprets every existing path as a text file without enforcing: - An approved workspace or input directory - Expected file extensions or content types - CSV schema validation - File-size limits - Rejection of path traversal or sensitive operating-system locations - Explicit user confirmation before upload Consequently, the process can read any UTF-8-compatible file accessible to its operating-system account. The inventory workflow only requires access to seller-selected sales and inventory files, so unrestricted access to unrelated local files exceeds the minimum privilege necessary for the declared functionality. The loaded content is inserted into fields such as `sales_data`, `current_stock`, or `inventory_data` and transmitted to the configured API. A ...[truncated 1711 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/yufluent_api.py:21
Finding

API Credential and Inventory Data Can Be Sent to an Arbitrary Plaintext Endpoint

Content
View full analysis
str: base = (base_url or "").strip().rstrip("/") if not base: base = "http://localhost:8080/v1" if base.endswith("/v1"): return base return f"{base}/v1" ``` The API key is placed in the Authorization header: ```python def _auth_headers(api_key: str) -> dict[str, str]: return { "Authorization": f"Bearer {api_key}", "Accept": "application/json", } ``` The environment-controlled destination receives both the credential and payload: ```python root = base_url or os.getenv("TOKENAPI_BASE_URL", "") url = skill_run_url(root, skill_id) try: resp = _post_json(url, api_key=key, body=payload, timeout=timeout) ``` ### Technical Analysis `TOKENAPI_BASE_URL` is accepted without validation of its scheme, hostname, port, or trust boundary. The implementation does not require HTTPS for remote hosts and does not restrict destinations to an approved Yufluent service or a loopback proxy. The documented default of `http://localhost:8080/v1` can be reasonable when communicating with a trusted local service. However, the same code accepts a non-loopback HTTP URL. In that case, the Bearer API key and seller inventory payload travel without transport encryption and may be intercepted or modified. The arbitrary-host behavior also creates a direct credential-redirection risk. Any party capable of influencing the process environment, invocation parameters, deployment configuration, or wrapper configuration can redirect requests to an attacker-controlled endpoint. HTTPS certificate verification provided by `request ...[truncated 2028 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (16)

Tainted flow: 'url' from os.getenv (line 271, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
92% confidence
Finding

The client allows the destination base URL to come from an environment variable and defaults to plain HTTP on localhost. Because the same request carries the bearer token and user payload, a malicious or misconfigured TOKENAPI_BASE_URL can redirect sensitive inventory data and credentials to an attacker-controlled endpoint or send them unencrypted. In this skill context, the risk is elevated because the payload likely contains business-sensitive inventory and sales data, not just low-value metadata.

Content

Scanner excerpt · scripts/yufluent_api.py (reported line 150)May include surrounding context.

python
}
    if body is not None:
        kwargs["json"] = body
    return requests.post(url, **kwargs)


def _raise_for_status(resp: requests.Response) -> None:

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个面向库存管理的业务技能,应处理销量/库存数据并生成分析结果。但提供的代码片段只是 bootstrap 辅助脚本,作用是查找本地目录结构并配置 Python 导入路径,属于基础设施/加载器代码。它未体现任何与库存预测、补货建议、滞销预警、资金占用分析相关的实际行为。因此,就该代码片段本身而言,实际行为与声明用途存在明显不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

该代码片段是一个通用云端/CLI 薄客户端工具库,而不是库存管理分析实现。其功能集中在:1)把参数当作文件路径读取文本;2)将本地图像转为 data URI,或透传 http(s)/data 源;3)从返回数据中选择 formatted_text/text/data/listing 打印;4)输出 run_id、model、token 等元信息。这与声明的核心业务目的——基于销量/库存数据进行预测分析并生成补货等建议——没有直接对应关系。虽然这类工具代码可能作为某技能的配套基础设施存在,但就该代码片段本身而言,其实际行为与声明用途存在明显不一致,且还包含了声明中未提及的图像处理能力。

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 28)May include surrounding context.

md
## 快速开始(3 步,60 秒)

1. **注册获取 API 密钥** → https://claw.changzhiai.com/login (新用户即送体验积分,无需绑卡)
2. **设置环境变量**:export TOKENAPI_KEY=*** 或写入 .env 文件
3. **运行**:参照下方 Examples 示例执行 python scripts/run.py ...

> 还没注册?前往 https://claw.changzhiai.com/login 免费获取密钥。

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill documentation and usage instructions are presented only in Chinese, which imposes a specific language on users without indicating any opt-in or alternative locale. This matches the policy category for language or locale constraints that are not optional or explicitly justified.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding

The skill explicitly requires environment access, file input, and network access, yet it does not declare a restrictive tool scope such as allowed-tools or permissions. This creates an authorization gap where an agent or runtime may grant broader capabilities than users expect, increasing the chance of unintended file access or outbound transmission of seller data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill says analysis is performed via a cloud Harness and instructs users to provide sales and inventory data, but it does not prominently warn that these business-sensitive datasets are transmitted off-device. This is dangerous because seller sales history, stock levels, and aging data can reveal proprietary operations and may be sent to a third-party service without informed consent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger list contains broad phrases such as '库存管理' and 'inventory forecast' that could match routine conversation and invoke the skill unexpectedly. In this skill's context, accidental activation is more dangerous because it may cause local business files to be read and transmitted to a cloud service without the user clearly intending that action.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This CLI collects potentially sensitive business data including sales history, inventory levels, stock aging, lead times, and unit costs, then sends it to a cloud service via run_skill() without any visible disclosure, consent prompt, or warning in this file. In the context of an inventory-management skill, such transmission is expected for functionality, but the lack of explicit user-facing notice increases the risk of unintentional exposure of commercially sensitive data to a remote service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The client defaults to an HTTP base URL at L024 and later sends request bodies and an Authorization bearer token via requests.post. Although the module docstring identifies it as a cloud thin client, there is no user-facing warning, confirmation, or comment near the network operations disclosing that user-provided payload data and credentials will be transmitted to a remote service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language prompt construction uses Chinese-only instructions such as '请直接执行技能' and other user-facing/error text throughout the file, implying a fixed language behavior. There is no opt-in, locale selection, or documented region-specific justification, which conflicts with the policy against forcing a specific language without user choice.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a skill for inventory forecasting, replenishment advice, slow-moving stock warnings, and capital occupancy analysis, all framed as producing structured JSON from seller data. This file also implements record_outcome(), which posts data to /v1/agent/outcomes to register Harness effects/telemetry; that capability is not part of the described inventory-analysis function and is not justified by the manifest text.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified as requests>=2.31.0, which allows any future major or minor release to be installed. This undermines build reproducibility and can unexpectedly introduce vulnerable or incompatible versions if upstream releases change, making supply-chain risk harder to control.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.31.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

The manifest references requests without pinning to a specific reviewed version, while multiple known advisories exist across historical releases. Because the exact installed version is not fixed, deployments could resolve to an affected version or later problematic release, leaving security posture unverifiable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The natural-language text in the module docstring and function docstrings is exclusively in Chinese, which can amount to a language policy constraint if this skill is expected to be usable across locales. The file does not indicate user choice, opt-in, or a documented region-specific justification for this language restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The --lang argument is hard-coded to default to 'zh', causing the skill to prefer Chinese unless the user overrides it. This is a natural-language locale choice imposed by default rather than selected by the user.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.