Back to skill

Security audit

Cue 搭子

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Cue template-authoring purpose, but it includes a built-in self-update path and automatic update check that can change or phone home about the installed skill outside the core workflow.

Install only if you are comfortable giving the skill network access to Cue, access to your CUE_API_KEY, local runtime storage under ~/.cue or CUE_HOME, and the ability to run its documented update checker. Avoid setting CUE_API_BASE except to a trusted Cue endpoint, do not allow the unlisted upload helpers to be used for private materials, and treat +upgrade as an admin action that should be run only after reviewing the source and update target.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tainted flow: 'req' from os.environ.get (line 1014, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
req.add_header("Authorization", f"Bearer {api_key}")
    req.add_header("Content-Type", f"multipart/form-data; boundary={boundary}")
    try:
        resp = urllib.request.urlopen(req, timeout=timeout)
    except urllib.error.HTTPError as e:
        detail = e.read().decode("utf-8", errors="replace")[:400]
        raise CueAPIError(e.code, detail, "/file_server/upload") from e
Confidence
77% confidence
Finding
upload_file() transmits full local file contents plus the bearer token to a server chosen by configuration, and there is no host allowlist or explicit trust boundary enforcement. If CUE_API_BASE or config.json is tampered with, sensitive local files and credentials could be sent to an attacker-controlled endpoint.

Tainted flow: 'req' from os.environ.get (line 1014, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
req.add_header("Content-Type", f"multipart/form-data; boundary={boundary}")
    req.add_header("Accept", "text/event-stream")
    try:
        resp = urllib.request.urlopen(req, timeout=timeout)
    except urllib.error.HTTPError as e:
        detail = e.read().decode("utf-8", errors="replace")[:400]
        raise CueAPIError(e.code, detail, "/file/upload_stream") from e
Confidence
80% confidence
Finding
upload_material() uploads entire local documents for parsing and embedding, which is more sensitive than ordinary metadata API calls. Because the destination base URL is configurable and unchecked, a poisoned environment/config could redirect both document contents and API credentials to an attacker-controlled service.

Tainted flow: 'env' from os.environ.get (line 847, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
env = {"GIT_AUTHOR_NAME": "T", "GIT_AUTHOR_EMAIL": "t@t",
               "GIT_COMMITTER_NAME": "T", "GIT_COMMITTER_EMAIL": "t@t",
               "PATH": os.environ.get("PATH", "")}
        subprocess.run(["git", "init", "-q", "-b", "main", str(tmp)],
                       check=True, env=env)
        (tmp / "file.txt").write_text("hi")
        subprocess.run(["git", "-C", str(tmp), "add", "."],
Confidence
78% confidence
Finding
The test constructs the subprocess environment using PATH from os.environ and then invokes git by bare program name. If an attacker can influence PATH in the execution environment, the test may execute a malicious git binary, causing unintended code execution in CI or developer machines.

Tainted flow: 'env' from os.environ.get (line 847, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
subprocess.run(["git", "init", "-q", "-b", "main", str(tmp)],
                       check=True, env=env)
        (tmp / "file.txt").write_text("hi")
        subprocess.run(["git", "-C", str(tmp), "add", "."],
                       check=True, env=env)
        subprocess.run(["git", "-C", str(tmp), "commit", "-q", "-m", "init"],
                       check=True, env=env)
Confidence
78% confidence
Finding
This subprocess call inherits the same PATH-derived environment as the earlier git init call. In compromised CI/dev environments, PATH hijacking could redirect execution to a malicious binary even though the argument list itself is static.

Tainted flow: 'env' from os.environ.get (line 847, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
(tmp / "file.txt").write_text("hi")
        subprocess.run(["git", "-C", str(tmp), "add", "."],
                       check=True, env=env)
        subprocess.run(["git", "-C", str(tmp), "commit", "-q", "-m", "init"],
                       check=True, env=env)

    def test_current_branch_returns_main_after_init(self) -> None:
Confidence
78% confidence
Finding
Although the command arguments are fixed, the executable lookup still depends on inherited PATH content. That makes the test susceptible to environment-based binary hijacking rather than classic command injection.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill exposes powerful capabilities—environment access, file read/write, network, and shell execution—without any explicit permission declaration or narrowing. That increases the chance that a host agent will grant broader access than users expect, especially because the skill also documents write operations, API calls, and local upgrade behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The manifest frames this as a public-data template-authoring skill, but the documented behavior extends well beyond that into arbitrary chat streaming, replay, query rewrite, local file upload/indexing, capability inventory, and self-upgrade. This mismatch can mislead users and orchestrators about the true attack surface, causing sensitive data exposure or unexpected remote actions under a lower-trust classification.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
A skill advertised as public-data-only template tooling should not silently include software-maintenance behavior that reaches out to GitHub and modifies the local installation. Even with confirmation for full upgrade, the added updater surface changes the trust model and can lead to supply-chain or local-integrity risks if users or platforms treat the skill as low-risk content tooling.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The `+upgrade` verb introduces a software-maintenance and supply-chain capability unrelated to the core template-authoring function. Fetching from GitHub and performing local `git pull` allows remote code changes to enter the environment, which is especially risky in an agent skill that otherwise appears to be a business workflow helper.

Description-Behavior Mismatch

Medium
Confidence
84% confidence
Finding
The skill manifest says the surface is for public-data template authoring/submission, but this client also exposes document upload and live research/conversation primitives that materially expand what the skill can do. That mismatch increases the chance an agent uses undeclared capabilities to transmit local content or run broader remote workflows than users expect.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill adds self-update and remote-pull behavior that is outside the declared business purpose of authoring and testing research templates. In an agent-skill context, bundling code-update capability expands the trust boundary and creates a supply-chain risk path where a skill can modify itself from a remote repository, which is more dangerous than ordinary template tooling.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The code performs git fetch and git pull operations that can change local skill code based on remote repository state, despite that behavior not being necessary for the skill's stated end-user function. In a security-sensitive agent environment, allowing a skill to update executable content increases supply-chain exposure and can let future remote changes alter agent behavior without normal review controls.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
upload_file() sends the full contents of a local file to a remote service without an explicit user-facing warning at the operation point. In an agent-skill context, that can surprise users and cause unintended disclosure of local documents, even if the intended backend is legitimate.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
upload_material() uploads and embeds full local documents for later semantic retrieval, which is a substantial privacy action. The lack of explicit runtime disclosure is especially risky because users may not realize the entire document is being parsed, chunked, indexed, and retained remotely.

Session Persistence

Medium
Category
Rogue Agent
Content
| `+unfrequent <template_id>` | 取消"常用",从首页"常用"区移除 | 否 | `POST /api/templates/frequent` (`is_frequent=false`) |
| `+upgrade` | 检查并(经确认后)升级 skill 自身到 GitHub `main` 最新版。git clone 装的走 `git pull --ff-only`,copy 装的给手动指引;本地有未提交改动则 abort 不强覆盖。**注意:跟 `+update <template_id>`(改模板)语义完全不同** | 否 | (GitHub raw + `git pull`,**本地操作**) |

**全部已上线 verb**:`+author / +capabilities / +validate / +create / +list / +get / +update / +test / +tune / +frequent / +unfrequent / +upgrade`。

**`+upgrade` 与 session 启动 silent-check**:agent 加载本 SKILL.md 时,**建议**在跑任何 verb 前先 silent 跑一次:`python3 cue-buddy/scripts/update_skill.py --silent-check`。这是带 24h 冷却的轻量版本对比,落后时只在 stderr 打一行 `ℹ️ cue-skills/cue-buddy 有新版可用 vX → vY,运行 +upgrade 升级`,**不弹问、不阻塞、不自动 pull**。网络失败时静默跳过(下次再试)。冷却 timestamp 存 `~/.cue/last-update-check.json`。
Confidence
79% confidence
Finding
The skill instructs a silent session-start update check with a 24-hour cooldown persisted to `~/.cue/last-update-check.json`. This creates cross-session state and outbound network behavior without explicit user initiation, which can leak usage metadata, surprise users, and weaken the expectation that the skill only acts when commanded.

Static analysis

No suspicious patterns detected.