Back to skill

Security audit

Yufluent Clawhub Publish Yufluentcn Seo Pro

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent cloud-backed SEO keyword tool, but it needs Review because its configurable API endpoint can receive the user's bearer token and business inputs without HTTPS or host restrictions.

Install only if you trust the Yufluent service and the environment configuration. Keep TOKENAPI_BASE_URL unset or set it only to a trusted HTTPS Yufluent endpoint or local development server, protect and rotate TOKENAPI_KEY like a password, avoid submitting highly sensitive competitive data unless the service terms are acceptable, and prefer a pinned dependency or lockfile for production use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/yufluent_api.py:21
Finding

Bearer Token and Business Data May Be Transmitted over Cleartext HTTP

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" ``` ```python def _auth_headers(api_key: str) -> dict[str, str]: return { "Authorization": f"Bearer {api_key}", "Accept": "application/json", } ``` ```python def _post_json( url: str, *, api_key: str, body: dict[str, Any] | None = None, timeout: float, ) -> requests.Response: kwargs: dict[str, Any] = { "headers": _json_headers(api_key) if body is not None else _auth_headers(api_key), "timeout": timeout, } if body is not None: kwargs["json"] = body return requests.post(url, **kwargs) ``` ```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 client accepts `TOKENAPI_BASE_URL` without validating its scheme or destination. It then sends `TOKENAPI_KEY` as a bearer token in the `Authorization` header and submits the user-provided SEO payload to that endpoint. The default endpoint uses HTTP on localhost, which is ordinarily limited to local traffic. However, the implementation also permits a non-loopback endpoint such as `http://remote-host/v1`. In that configuration, the bearer token and payload are transmitted without TLS confidentiality or server authentication. The transmitted payload can include product names, seed keywords, competitor keywords, target markets, ...[truncated 1862 chars]
Remediation
View remediation
str: normalized = normalize_api_root(base_url) parsed = urlparse(normalized) if parsed.scheme not in {"http", "https"}: raise ValueError("API URL must use HTTP or HTTPS") host = parsed.hostname or "" loopback = host == "localhost" if not loopback: try: loopback = ipaddress.ip_address(host).is_loopback except ValueError: loopback = False if parsed.scheme != "https" and not loopback: raise ValueError("HTTPS is required for non-loopback API endpoints") return normalized ``` ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded Dependency Version Prevents Reproducible and Controlled Installation

Content
View full analysis
=2.31.0 ``` The same unconstrained installation rule is included in the Skill metadata: ```text "packages":["requests>=2.31.0"] ``` ### Technical Analysis The dependency declaration specifies only a minimum version. Consequently, an installation can resolve to any future version of `requests` accepted by the package resolver. There is no lockfile, exact version constraint, upper bound, or package hash to make installation reproducible and integrity-verifiable. No evidence was found that the currently declared `requests` package is malicious, misspelled, or retrieved from a custom untrusted index. This finding concerns supply-chain exposure and reproducibility rather than a confirmed compromise of the present dependency. Because `requests` is imported directly by `scripts/yufluent_api.py`, code installed under that package name executes in the Skill's Python process. It consequently runs with the same local privileges as the user invoking the Skill and can access data available to that process, including the API token and request payload. ### Attack Path 1. A user or automation installs dependencies using `requirements.txt` or the package specification embedded in `SKILL.md`. 2. The package resolver selects a newer release because no exact version, upper bound, or integrity hash is enforced. 3. If a future selected release or its distribution channel is compromised, the untrusted package is installed. 4. `scripts/yufluent_api.py` imports `requests`. 5. Package initialization code runs with the invoking user's privileges. 6. A compromised dependency could read process-accessible data, including `TOKENAPI_KEY`, modify outbound requests, execute local actions, or transmit information externally. This path requires compromise of a future depe ...[truncated 849 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (15)

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The HTTP client accepts a base URL from an environment variable and uses it to construct authenticated requests, including a Bearer token and arbitrary payload data. If an attacker can influence TOKENAPI_BASE_URL or the base_url parameter, they can redirect requests to an attacker-controlled server and exfiltrate credentials and task data, which is a classic SSRF/credential-leak pattern.

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:

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 · README.md (reported line 10)May include surrounding context.

powershell
cd skills\yufluentcn-seo-pro
pip install -r requirements.txt
copy .env.example .env
# 编辑 TOKENAPI_KEY = "tk-***"

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 32)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 entire skill description and usage documentation are presented only in Chinese, including the user-facing guidance and linked documentation labels. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The trigger list contains generic phrases such as "关键词研究", "SEO 优化", and "标题埋词怎么布局", which are common requests in normal ecommerce or marketing conversations and are not narrowly scoped to this specific skill. The section does not provide exclusion conditions or negative examples to clarify when the skill should not activate.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The docstring at L02 describes the module as 'ClawHub 云端薄客户端', implying it is a thin client for ClawHub. However, the implementation uses argparse text 'TokenApi SEO Pro(云端)' at L27 and calls run_skill with SKILL_API_ID set to 'seo-pro' at L23, indicating a different service/backend. This is an active documentation-to-code contradiction rather than a mere omission.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code sets --lang to zh by default, which forces a specific language/locale behavior unless the user explicitly overrides it. This is a natural-language policy concern because the skill does not offer a neutral default or documented opt-in for the language choice.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
76% confidence
Finding

The top-level documentation presents this module as a simple cloud thin client, which implies straightforward skill API access. In practice, the module also posts to /agent/outcomes and falls back from /skills/{id}/run to /agent/turn, changing behavior from direct skill invocation to a wider orchestration path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This helper sends JSON bodies and authorization headers to remote endpoints via requests.post, and it is used by run_skill and record_outcome to transmit caller-provided payloads. While the network behavior is integral to an API client, this file provides no confirmation prompt, print/log disclosure, or comment/docstring warning that user or system data may be sent to a remote service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This function reads TOKENAPI_KEY from the environment and POSTs the supplied payload to /v1/agent/outcomes, which may include user or system outcome data. The function has no user-facing notice, confirmation, or warning describing that authenticated telemetry-like data is being transmitted to an external service.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with a lower bound only (requests>=2.31.0), which allows installation of different future versions and makes builds non-reproducible. This increases supply-chain risk because a later incompatible or vulnerable release could be pulled without review, and it also prevents clear verification of what code is actually installed.

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
89% confidence
Finding

Because requests is not pinned to a specific version, it is impossible to verify from this manifest whether the installed package includes fixes for known advisories or whether a vulnerable release may be selected. The danger here is uncertainty and auditability failure rather than proof of a specific exploitable CVE in this file alone.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module docstring is written entirely in Chinese and presents the skill behavior in that language without offering any language or locale choice. The policy requires flagging language or locale constraints when they are imposed without explicit user opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This Python file contains user-facing natural-language text exclusively in Chinese in docstrings and error/context descriptions, with no indication that the skill is region-specific or that users may choose another language. The policy for SQP-3 flags language or locale constraints when they are imposed without opt-in or clear justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

run_skill reads TOKENAPI_KEY from the environment and uses it for authenticated remote requests, but the surrounding text only tells the user how to set the variable, not that the skill consumes a credential for outbound authentication. Under this rule, sensitive environment-variable access should have some disclosure or explanatory warning when no other visible warning is present in the file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.