Back to skill

Security audit

Zhuge Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed football prediction tool that uses chosen sports and LLM APIs plus local files, with setup and data-quality risks but no evidence of hidden upload or malicious behavior.

Install only if you are comfortable with a local CLI tool that stores API keys in a plaintext .env file, calls the sports and LLM providers you configure, and may persist public crystal data pulled from GitHub. Avoid relay mode unless you trust that proxy, prefer a virtual environment, and treat crystal-based confidence as unverified because remote crystal data is not schema-validated.

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/sync.py:91
Finding

Unvalidated Remote Crystal Data Is Persisted and Trusted by Prediction Logic

Content
View full analysis
List[Dict]: """加载所有晶体(本地 + 共享)""" crystals = [] for path in [CRYSTALS_LOCAL, CRYSTALS_SHARED]: if path.exists(): with open(path, encoding="utf-8") as f: for line in f: if line.strip(): try: crystals.appen ...[truncated 3288 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
core/wizard.py:90
Finding

Mutable Unpinned Dependencies Are Installed at Runtime Without Integrity Verification

Content
View full analysis
=2.28 python-dotenv>=1.0 ``` ```python if not deps_ok: print() if confirm("现在自动安装依赖?", default=True): os.system(f"{sys.executable} -m pip install -q requests python-dotenv") print(f" {GREEN}✓{RESET} 依赖已安装") else: print(f" {GRAY}跳过依赖安装。手动跑: pip install -r requirements.txt{RESET}") ``` ### Technical Analysis The dependency manifest specifies only minimum versions and no upper bounds or cryptographic hashes. The interactive wizard additionally installs unconstrained current versions directly from the user’s configured pip source. This creates a mutable installation result: identical Skill versions can install different dependency versions over time. The process also depends on the integrity of the configured package index, mirrors, transport configuration, and all transitive dependencies selected at installation time. The installation is user-confirmed, which reduces unexpected execution, and the package names are legitimate rather than apparent typosquats. Nevertheless, the absence of version locking and hash verification leaves the setup path exposed to compromised future releases, compromised indexes or mirrors, and incompatible dependency updates. The wizard uses `os.system()` and does not inspect the installation command’s exit status before reporting success. Although `sys.executable` is not directly derived from interactive input, invoking package installation through a shell is unnecessary and weaker than an argument-vector subprocess call. ### Attack Path 1. The user starts the Skill without `requests` installed. 2. The wizard offers automatic dependency installation, with acceptance as the default response. 3. The user approves installation. 4. Pip resolves the latest ...[truncated 1156 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (79)

Tainted flow: 'key' from os.getenv (line 18, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · adapters/the_odds.py (reported line 28)May include surrounding context.

python
try:
        import requests
        r = requests.get(f"{BASE}/sports/{sport_key}/odds",
                         params={"apiKey": key, "regions": "us,uk,eu",
                                 "markets": "h2h,totals", "oddsFormat": "decimal"},
                         timeout=timeout)

Direct flow: os.getenv (credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/backfill.py (reported line 71)May include surrounding context.

python
return None
    try:
        import requests
        r = requests.get("https://v3.football.api-sports.io/fixtures",
                         headers={"x-apisports-key": os.getenv("API_FOOTBALL_KEY")},
                         params={"id": api_fid}, timeout=15)
        if not r.ok:

Tainted flow: 'REMOTE_URL' from os.getenv (line 43, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/sync.py (reported line 91)May include surrounding context.

python
print(f"\n  从公共仓库拉取: {DIM}{REMOTE_URL}{RESET}")
    print(f"  {DIM}(此请求是只读的 HTTP GET,不携带任何本地数据){RESET}")
    try:
        r = requests.get(REMOTE_URL, timeout=10)
        if not r.ok:
            print(f"  {RED}拉取失败 (HTTP {r.status_code}){RESET}")
            print(f"  {DIM}(可能仓库还没建。也可以手动维护 data/crystals_shared.jsonl){RESET}\n")

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

md
### Fixed
- **坑 #15**: `.env` 只填 `DEEPSEEK_API_KEY` 但没写 `LLM_PROVIDER=deepseek` → LLM 静默不调用 (2026-04-18 晚朋友实测踩到)
- **缺失 `.env.example`**: README 引用它但文件不存在 (朋友无从下手) · 补上 · 把 LLM_PROVIDER 必要性 + Windows 编码坑都标红
- **README 30 秒上手**: 重写成 5 步真实流程 (clone / 装依赖 / .env / 编码 / 启动), 加两个坑显著提示
- **sync.py docstring**: 陈旧远程 URL `taijios9/zhuge-crystals` → `yangfei222666-9/zhuge-crystals`

### Note

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 39)May include surrounding context.

md
### Fixed
- **坑 #15**: `.env` 只填 `DEEPSEEK_API_KEY` 但没写 `LLM_PROVIDER=deepseek` → LLM 静默不调用 (2026-04-18 晚朋友实测踩到)
- **缺失 `.env.example`**: README 引用它但文件不存在 (朋友无从下手) · 补上 · 把 LLM_PROVIDER 必要性 + Windows 编码坑都标红
- **README 30 秒上手**: 重写成 5 步真实流程 (clone / 装依赖 / .env / 编码 / 启动), 加两个坑显著提示
- **sync.py docstring**: 陈旧远程 URL `taijios9/zhuge-crystals` → `yangfei222666-9/zhuge-crystals`

### Note

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 40)May include surrounding context.

md
### Fixed
- **坑 #15**: `.env` 只填 `DEEPSEEK_API_KEY` 但没写 `LLM_PROVIDER=deepseek` → LLM 静默不调用 (2026-04-18 晚朋友实测踩到)
- **缺失 `.env.example`**: README 引用它但文件不存在 (朋友无从下手) · 补上 · 把 LLM_PROVIDER 必要性 + Windows 编码坑都标红
- **README 30 秒上手**: 重写成 5 步真实流程 (clone / 装依赖 / .env / 编码 / 启动), 加两个坑显著提示
- **sync.py docstring**: 陈旧远程 URL `taijios9/zhuge-crystals` → `yangfei222666-9/zhuge-crystals`

### Note

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 297)May include surrounding context.

md
### Fixed
- **坑 #15**: `.env` 只填 `DEEPSEEK_API_KEY` 但没写 `LLM_PROVIDER=deepseek` → LLM 静默不调用 (2026-04-18 晚朋友实测踩到)
- **缺失 `.env.example`**: README 引用它但文件不存在 (朋友无从下手) · 补上 · 把 LLM_PROVIDER 必要性 + Windows 编码坑都标红
- **README 30 秒上手**: 重写成 5 步真实流程 (clone / 装依赖 / .env / 编码 / 启动), 加两个坑显著提示
- **sync.py docstring**: 陈旧远程 URL `taijios9/zhuge-crystals` → `yangfei222666-9/zhuge-crystals`

### Note

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 298)May include surrounding context.

md
### Fixed
- **坑 #15**: `.env` 只填 `DEEPSEEK_API_KEY` 但没写 `LLM_PROVIDER=deepseek` → LLM 静默不调用 (2026-04-18 晚朋友实测踩到)
- **缺失 `.env.example`**: README 引用它但文件不存在 (朋友无从下手) · 补上 · 把 LLM_PROVIDER 必要性 + Windows 编码坑都标红
- **README 30 秒上手**: 重写成 5 步真实流程 (clone / 装依赖 / .env / 编码 / 启动), 加两个坑显著提示
- **sync.py docstring**: 陈旧远程 URL `taijios9/zhuge-crystals` → `yangfei222666-9/zhuge-crystals`

### Note

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 182)May include surrounding context.

md
### Fixed
- **坑 #15**: `.env` 只填 `DEEPSEEK_API_KEY` 但没写 `LLM_PROVIDER=deepseek` → LLM 静默不调用 (2026-04-18 晚朋友实测踩到)
- **缺失 `.env.example`**: README 引用它但文件不存在 (朋友无从下手) · 补上 · 把 LLM_PROVIDER 必要性 + Windows 编码坑都标红
- **README 30 秒上手**: 重写成 5 步真实流程 (clone / 装依赖 / .env / 编码 / 启动), 加两个坑显著提示
- **sync.py docstring**: 陈旧远程 URL `taijios9/zhuge-crystals` → `yangfei222666-9/zhuge-crystals`

### Note

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 · core/wizard.py (reported line 135)May include surrounding context.

python
### Fixed
- **坑 #15**: `.env` 只填 `DEEPSEEK_API_KEY` 但没写 `LLM_PROVIDER=deepseek` → LLM 静默不调用 (2026-04-18 晚朋友实测踩到)
- **缺失 `.env.example`**: README 引用它但文件不存在 (朋友无从下手) · 补上 · 把 LLM_PROVIDER 必要性 + Windows 编码坑都标红
- **README 30 秒上手**: 重写成 5 步真实流程 (clone / 装依赖 / .env / 编码 / 启动), 加两个坑显著提示
- **sync.py docstring**: 陈旧远程 URL `taijios9/zhuge-crystals` → `yangfei222666-9/zhuge-crystals`

### Note

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 · core/wizard.py (reported line 140)May include surrounding context.

python
### Fixed
- **坑 #15**: `.env` 只填 `DEEPSEEK_API_KEY` 但没写 `LLM_PROVIDER=deepseek` → LLM 静默不调用 (2026-04-18 晚朋友实测踩到)
- **缺失 `.env.example`**: README 引用它但文件不存在 (朋友无从下手) · 补上 · 把 LLM_PROVIDER 必要性 + Windows 编码坑都标红
- **README 30 秒上手**: 重写成 5 步真实流程 (clone / 装依赖 / .env / 编码 / 启动), 加两个坑显著提示
- **sync.py docstring**: 陈旧远程 URL `taijios9/zhuge-crystals` → `yangfei222666-9/zhuge-crystals`

### Note

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 · scripts/predict.py (reported line 297)May include surrounding context.

python
### Fixed
- **坑 #15**: `.env` 只填 `DEEPSEEK_API_KEY` 但没写 `LLM_PROVIDER=deepseek` → LLM 静默不调用 (2026-04-18 晚朋友实测踩到)
- **缺失 `.env.example`**: README 引用它但文件不存在 (朋友无从下手) · 补上 · 把 LLM_PROVIDER 必要性 + Windows 编码坑都标红
- **README 30 秒上手**: 重写成 5 步真实流程 (clone / 装依赖 / .env / 编码 / 启动), 加两个坑显著提示
- **sync.py docstring**: 陈旧远程 URL `taijios9/zhuge-crystals` → `yangfei222666-9/zhuge-crystals`

### Note

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · core/welcome.py (reported line 9)May include surrounding context.

python
# 启用 Windows ANSI
if sys.platform == "win32":
    os.system("")

# === 256 色赛博调色板 ===
RESET = "\033[0m"

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 183)May include surrounding context.

md
NEON_PURPLE as PURPLE, RESET)

ROOT = Path(__file__).resolve().parent.parent
ENV_FILE = ROOT / ".env"
ENV_EXAMPLE = ROOT / ".env.example"

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 · core/wizard.py (reported line 12)May include surrounding context.

python
NEON_PURPLE as PURPLE, RESET)

ROOT = Path(__file__).resolve().parent.parent
ENV_FILE = ROOT / ".env"
ENV_EXAMPLE = ROOT / ".env.example"

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 · scripts/predict.py (reported line 30)May include surrounding context.

python
NEON_PURPLE as PURPLE, RESET)

ROOT = Path(__file__).resolve().parent.parent
ENV_FILE = ROOT / ".env"
ENV_EXAMPLE = ROOT / ".env.example"

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The write_env() function persists provided values, including API keys, into a plaintext .env file. While intended for configuration, storing secrets this way can expose credentials to other local users, backups, logs, or accidental repository commits if file permissions and ignore rules are not handled carefully.

Content

Scanner excerpt · core/wizard.py (reported line 56)May include surrounding context.

python
def write_env(values):
    """写 .env 文件"""
    lines = ["# 诸葛亮 · AI 推演军师 — 自动生成的配置\n"]
    for k, v in values.items():
        if v:

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

The wizard executes a shell command to install packages via os.system(), which invokes a shell unnecessarily and expands the attack surface compared with a direct subprocess call. In this specific code the interpolated value comes from sys.executable rather than user input, so it is not an obvious command injection sink, but it still performs system modification and could be unsafe in unusual environments where the interpreter path is manipulated or shell behavior is unexpected.

Content

Scanner excerpt · core/wizard.py (reported line 94)May include surrounding context.

python
if not deps_ok:
        print()
        if confirm("现在自动安装依赖?", default=True):
            os.system(f"{sys.executable} -m pip install -q requests python-dotenv")
            print(f"  {GREEN}✓{RESET} 依赖已安装")
        else:
            print(f"  {GRAY}跳过依赖安装。手动跑: pip install -r requirements.txt{RESET}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README advertises automatic sharing and pulling of user-derived 'crystals' across users, but does not clearly disclose what data leaves the local machine, what metadata is included, or whether sharing is opt-in by default. In an agent-skill context, silent or poorly disclosed synchronization of user-derived data can leak behavioral history, prompts, predictions, or other derived artifacts to third parties.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README documents a looped backfill/daemon mode that runs every 30 minutes, but does not clearly warn that this causes ongoing background execution and repeated network access. In an agent environment, undocumented continuous activity can surprise users, increase attack surface, consume quotas, and violate host expectations for passive tools.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The shared-pool description says crystals may be pushed to GitHub Release and other agents' data may be pulled, but it lacks a clear warning that using the feature uploads locally derived data to a remote service. Without explicit disclosure and consent, this can expose user-generated artifacts and create supply-chain trust issues when ingesting shared data from others.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document presents the skill name, descriptions, instructions, and example prompt entirely in Chinese, including the suggested agent invocation text. This creates a language/locale constraint for users without any explicit opt-in or alternative-language guidance in the skill file, which matches the policy concern for forced language selection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The file's top-level description and embedded documentation are written in Chinese, which imposes a specific language context without any indication of user choice or opt-in. Under the stated policy, forced language/locale behavior should be flagged unless choice or justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module title and function docstring are written in Chinese, which imposes a specific language in user-visible natural-language text without offering any language choice or documenting a justified locale restriction. The policy requires avoiding forced language or locale unless the user can opt in or the constraint is clearly documented.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · adapters/the_odds.py (reported line 5)May include surrounding context.

python
import os
from typing import Dict, Optional

BASE = "https://api.the-odds-api.com/v4"
SPORT_KEYS = {
    "premier-league": "soccer_epl",
    "la-liga": "soccer_spain_la_liga",

Static analysis

No suspicious patterns detected.