Back to skill

Security audit

IELTS Reading Review 雅思阅读复盘

Security checks for vulnerabilities and agentic risk

Overview

This IELTS review skill has a real study use, but it also auto-updates itself, uploads review data, stores long-lived tokens, scans broad personal folders, and can run production deployment commands with insufficient user control.

Review this carefully before installing. Disable or remove the prompt auto-update hook, avoid author mode on machines with production SSH access, use a dedicated short-lived token stored outside shell startup files, require explicit confirmation before any upload or folder scan, and treat the README's offline claims as stale because the current skill is web-connected.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
Findings (7)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:12
Finding

Mandatory workflow overrides user intent and forces remote upload

Content
View full analysis
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
hooks/auto-update.sh:17
Finding

Prompt hook performs unattended remote Skill replacement

Content
View full analysis
&1 || true) # 判断是否有更新 if echo "$CHECK_OUTPUT" | grep -q "有新版本可用"; then # 自动更新 UPDATE_OUTPUT=$(node "$CHECK_SCRIPT" --auto 2>&1 || true) NEW_VER=$(grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' "$SKILL_DIR/SKILL.md" 2>/dev/null | head -1 || echo "unknown") MSG="🔄 [IELTS Skill 自动更新] 本地 skill 版本落后,已自动更新到 $NEW_VER。**当前已加载的 skill 内容是旧版本**,必须重新告知用户:'检测到 skill 已自动更新,请重新发送你的复盘请求,Jarvis 将使用最新的 v$NEW_VER 流程处理。'" echo "{\"systemMessage\": \"$MSG\"}" ``` The update implementation executes: ```js execSync(`clawhub install ${SLUG} --force`, { cwd: userSkillsDir, encoding: 'utf-8', stdio: 'inherit' }); ``` ### Technical Analysis Submitting a prompt containing a broad trigger such as `IELTS` causes local command execution. If ClawHub reports a newer version, the hook invokes `clawhub install ... --force` without asking the user to approve that specific version or review its contents. This creates a post-audit payload channel: the code reviewed in the current package is not necessarily the code that will run later. A compromised publisher account, regi ...[truncated 1508 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup-client-mode.sh:187
Finding

Long-lived account token is persisted in plaintext shell startup files

Content
View full analysis
> "$RC" << EOF # IELTS Reading Review — 客户端 token (added by setup-client-mode.sh) export IELTS_USER_TOKEN='$TOKEN' EOF ``` `SKILL.md:675` states that the token is valid for ten years by default. ### Technical Analysis The script stores a bearer token directly in `.zshrc`, `.bashrc`, or `.profile`. Shell startup files are plaintext and are frequently read by terminal tools, IDEs, diagnostic utilities, backup systems, dotfile repositories, and other local processes. Because the token is exported, every descendant process of the shell receives it in its environment. This broadens exposure beyond the review application. The script does not set restrictive permissions, use an operating-system credential manager, define token scope, or provide automated expiration and rotation. The token is inserted into shell syntax inside single quotes without a dedicated shell-escaping routine. The automatic browser flow may normally issue a constrained token format, but manual mode accepts pasted input. A token containing a single quote and shell syntax could alter the generated startup file and execute commands when the user next starts or sources a shell. ### Attack Path Credential disclosure path: 1. The user completes client authorization. 2. The script appends ...[truncated 1050 chars]
Remediation
View remediation

other

Warning
Location
scripts/generate-pdf.js:13
Finding

PDF generation sends opt-out telemetry to an operator-controlled endpoint

Content
View full analysis
{}); req.on('timeout', () => req.destroy()); req.write(payload); req.end(); } ``` After successful PDF creation, line 80 calls: ```js reportAnonymousUsage('pdf_generated'); ``` ### Technical Analysis Local PDF generation does not require communication with a usage-statistics service, but the script sends an event, Skill version, and timestamp by default. Users must discover and set `SKILL_NO_TELEMETRY=1` to disable it. Although the request body does not contain a username, filename, or document content, the server and underlying network provider necessarily observe transport metadata such as the source IP and request timing. The included Worker stores event, version, and timestamp aggregates and daily logs. This is not a code-execution vulnerability, but it violates data-minimization and informed-consent principles because telemetry is unrelated to the requested PDF operation and defaults to enabled. ### Attack Path 1. A user generates a PDF locally. 2. The script successfully writes the PDF. 3. `reportAnonymousUsage('pdf_generated')` opens an HTTPS connection to the operator-controlled Worker. 4. The Worker receives the ev ...[truncated 402 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
assets/review-template.html:631
Finding

Generated pages execute an unpinned third-party script from a public CDN

Content
View full analysis
``` The production instructions also execute an unpinned dependency installation: ```bash ssh openclaw-tunnel "cd /home/ubuntu/ielts-api && npm install" ``` The Worker deployment script invokes `npx wrangler` without an audited pinned package version: ```bash npx wrangler login npx wrangler kv namespace create STATS npx wrangler deploy ``` ### Technical Analysis The review template loads `lucide@latest`, which is a mutable alias. The effective browser code can change after this Skill version has been audited. No Subresource Integrity hash is present, so a compromised package release, package account, registry, or CDN response could execute arbitrary JavaScript in the page’s origin context. Similarly, the production instructions use `npm install` and `npx wrangler` without an included lockfile or exact audited versions in this artifact. This prevents deterministic dependency resolution and expands supply-chain risk. No evidence was found that the current Lucide or Wrangler packages are malicious. The vulnerability is the use of mutable, unverified dependency sources in browser and deployment contexts. ### Attack Path Browser path: 1. An attacker compromises the package publisher, npm package, CDN, or mutable `latest` release. 2. A user opens a generated review page. 3. The browser requests `https://unpkg.com/lucide@latest`. 4. The compromised JavaScript executes in the page context. 5. It can read or modify page data and make network requests allowed by browser security policy. Deployment path: 1. A dependency or transitive dependency resolves to a compromised release. 2. An author f ...[truncated 586 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/scan-legacy-reviews.js:191
Finding

Default legacy-review discovery traverses broad personal directories

Content
View full analysis
{ if (seen.has(d)) return false; seen.add(d); return fs.existsSync(d); }); // 扩展候选:从每个候选根目录,把"直接子目录中带雅思/IELTS/reading/复盘/阅读"关键词的也加进来 const DIR_KEYWORDS = [/雅思/, /ielts/i, /reading/i, /复盘/, /阅读/, /ielts/i]; const extendedDirs = new Set(candidateDirs); for (const dir of candidateDirs) { try { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { if (!entry.isDirectory() || entry.name.startsWith('.')) continue; if (IGNORE_DIRS.has(entry.name)) continue; if (DIR_KEYWORDS.some((re) => re.test(entry.name))) { extendedDirs.add(path.join(dir, entry.name)); } } } catch (err) { /* skip */ } } candidateDirs = Array.from(extendedDirs); const discoveries = []; for (const dir of candidateDirs) { const hits = quickCount(dir, 3); ``` ### Technical Analysis When run without a directory argument, the utility enters automatic mode and traverses the current directory, Documents, Desktop, Downloads, iCloud Drive, and several additional home-directory paths. It recursively inspects entries and records matching filenames and modification times. Legacy-review discovery is part of the declared fea ...[truncated 1276 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:447
Finding

IELTS review Skill exposes excessive production deployment authority

Content
View full analysis
/var/www/ielts/dict_full.json.tmp && mv /var/www/ielts/dict_full.json.tmp /var/www/ielts/dict_full.json" ssh openclaw-tunnel "python3 -c \"import json; d=json.load(open('/var/www/ielts/dict_full.json', encoding='utf-8')); print(f'OK: {len(d)} words')\"" ``` ```bash scp -o ConnectTimeout=15 \ -o StrictHostKeyChecking=accept-new \ -o UserKnownHostsFile=~/.ssh/known_hosts_cfd \ -o "ProxyCommand=/Users/dengjiawei/bin/cloudflared access tcp --hostname ssh.tuyaya.online" \ -i ~/.ssh/workbuddy.pem \ <本地文件> ubuntu@ssh.tuyaya.online:/var/www/ielts/ ``` ```bash ssh openclaw-tunnel "cat > /home/ubuntu/ielts-api/index.js" < server/index.js ssh openclaw-tunnel "mkdir -p /home/ubuntu/ielts-api/lib" ssh openclaw-tunnel "cat > /home/ubuntu/ielts-api/lib/llmExtractor.js" < server/lib/llmExtractor.js ssh openclaw-tunnel "cat > /home/ubuntu/ielts-api/lib/schemaUpgrader.js" < server/lib/schemaUpgrader.js ssh openclaw-tunnel "cat > /home/ubuntu/ielts-api/lib/tencentOcr.js" < server/lib/tencentOcr.js ssh openclaw-tunnel "cd /home/ubuntu/ielts-api && npm install" ``` ```bash ssh openclaw-tunnel "sudo systemctl restart ielts-api" ``` ### Technical Analysis The author-mode workflow goes far beyond generating and uploading an IELTS review. It can overwrite production web data, replace backend JavaScript, create server directories, install npm dependencies, and restart a systemd service using `sudo`. The mode decision is based only on the presence of a specific SSH private-key file and alias. Once author mode is selected, the Skill’s mandatory workflow encourages the Agent to use powerful deployment operations. This tightly couples ordinary content processing with production ...[truncated 1524 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (73)

Harmful Content Injection

Critical
Category
Prompt Injection
Confidence
70% confidence
Finding

This content may contain harmful instructions that could cause physical harm if followed. CRITICAL: Review carefully before use.

Content

Scanner excerpt · references/error-taxonomy.md (reported line 137)May include surrounding context.

md
## Category 11: Category-Membership Reasoning Treated as Inference

**Description:** When the passage establishes "Category A has property B" and then states "X belongs to Category A", concluding "X has property B" is **direct information**, not inference. The test-taker wrongly treats this as over-inference and chooses NOT GIVEN.

**Examples:**
- Passage: "Shade-tolerant plants have lower growth rates" + "Eastern hemlock is shade-tolerant" → Eastern hemlock has lower growth rates. This is NOT inference — it's stated through category membership.
- Test-taker chose NOT GIVEN thinking "the passage doesn't directly say eastern hemlock has lower growth rates"

**Key Rule:** If the passage says "A-type things have X" and "Y is A-type", then "Y has X" is **a stated fact**, not inference. This is TRUE/FALSE territory, not NOT GIVEN.

**Improvement:** When you're leaning toward NOT GIVEN, check: did the passage put the subject into a category that was already described? If yes, the category's properties apply.

Harmful Content Injection

Critical
Category
Prompt Injection
Confidence
70% confidence
Finding

This content may contain harmful instructions that could cause physical harm if followed. CRITICAL: Review carefully before use.

Content

Scanner excerpt · references/error-taxonomy.md (reported line 138)May include surrounding context.

md
## Category 11: Category-Membership Reasoning Treated as Inference

**Description:** When the passage establishes "Category A has property B" and then states "X belongs to Category A", concluding "X has property B" is **direct information**, not inference. The test-taker wrongly treats this as over-inference and chooses NOT GIVEN.

**Examples:**
- Passage: "Shade-tolerant plants have lower growth rates" + "Eastern hemlock is shade-tolerant" → Eastern hemlock has lower growth rates. This is NOT inference — it's stated through category membership.
- Test-taker chose NOT GIVEN thinking "the passage doesn't directly say eastern hemlock has lower growth rates"

**Key Rule:** If the passage says "A-type things have X" and "Y is A-type", then "Y has X" is **a stated fact**, not inference. This is TRUE/FALSE territory, not NOT GIVEN.

**Improvement:** When you're leaning toward NOT GIVEN, check: did the passage put the subject into a category that was already described? If yes, the category's properties apply.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README describes receiving a token via a localhost callback and automatically writing it to ~/.zshrc, which creates credential persistence in a shell profile and modifies a sensitive startup file without prominent warning or safer storage guidance. If the token is long-lived or the profile is readable, this can expose credentials to other local processes, users, logs, backups, or later command output.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill includes credential acquisition and persistence behavior—guiding token extraction from browser storage and writing credentials into shell startup files—even though this is not a normal expectation for a reading-review tool. Credential handling expands the trust boundary substantially and risks accidental leakage, misuse, or persistence of sensitive tokens beyond the immediate task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill includes credential acquisition and persistence behavior—guiding token extraction from browser storage and writing credentials into shell startup files—even though this is not a normal expectation for a reading-review tool. Credential handling expands the trust boundary substantially and risks accidental leakage, misuse, or persistence of sensitive tokens beyond the immediate task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill includes credential acquisition and persistence behavior—guiding token extraction from browser storage and writing credentials into shell startup files—even though this is not a normal expectation for a reading-review tool. Credential handling expands the trust boundary substantially and risks accidental leakage, misuse, or persistence of sensitive tokens beyond the immediate task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill includes credential acquisition and persistence behavior—guiding token extraction from browser storage and writing credentials into shell startup files—even though this is not a normal expectation for a reading-review tool. Credential handling expands the trust boundary substantially and risks accidental leakage, misuse, or persistence of sensitive tokens beyond the immediate task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill includes credential acquisition and persistence behavior—guiding token extraction from browser storage and writing credentials into shell startup files—even though this is not a normal expectation for a reading-review tool. Credential handling expands the trust boundary substantially and risks accidental leakage, misuse, or persistence of sensitive tokens beyond the immediate task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill includes credential acquisition and persistence behavior—guiding token extraction from browser storage and writing credentials into shell startup files—even though this is not a normal expectation for a reading-review tool. Credential handling expands the trust boundary substantially and risks accidental leakage, misuse, or persistence of sensitive tokens beyond the immediate task.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The auto-scan/batch-import activation language is broad and encourages scanning the user's computer for historical notes without tight bounds. In context, this is more dangerous because the skill directs sweeping searches across Documents, Desktop, Downloads, and iCloud-like locations, which can expose unrelated personal data during an unexpectedly triggered workflow.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

The auto-scan/batch-import activation language is broad and encourages scanning the user's computer for historical notes without tight bounds. In context, this is more dangerous because the skill directs sweeping searches across Documents, Desktop, Downloads, and iCloud-like locations, which can expose unrelated personal data during an unexpectedly triggered workflow.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
> **v3.9.1 新增**:Step 0 自动版本检查(scripts/check-update.js),每次激活时比对本地与 ClawHub 版本。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
> **v3.9.1 新增**:Step 0 自动版本检查(scripts/check-update.js),每次激活时比对本地与 ClawHub 版本。

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The skill references direct use of SSH private key material and known-host configuration to access a remote server. Guidance that depends on local credential files inside a general-purpose skill increases the chance of credential misuse, accidental disclosure, or unauthorized reuse if the skill is invoked in the wrong environment.

Content

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

bash
scp -o ConnectTimeout=15 \
    -o StrictHostKeyChecking=accept-new \
    -o UserKnownHostsFile=~/.ssh/known_hosts_cfd \
    -o "ProxyCommand=/Users/dengjiawei/bin/cloudflared access tcp --hostname ssh.tuyaya.online" \
    -i ~/.ssh/workbuddy.pem \
    <本地文件> ubuntu@ssh.tuyaya.online:/var/www/ielts/

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

bash
# 用 getReviews 回查本篇是否真的入库(替换 BOOK/TEST/PASSAGE)
curl -s https://www.liuxue.online/api/ielts -H 'Content-Type: application/json' \
  -d '{"action":"getReviews","token":"<USER_TOKEN>","book":<BOOK>,"test":<TEST>}' \
  | python3 -c "
import json,sys

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

}, ensure_ascii=False)) " "$JSON_FILE" "$TOKEN")

curl -s -X POST https://www.liuxue.online/api/ielts
-H 'Content-Type: application/json'
-d "$PAYLOAD"

text

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

}, ensure_ascii=False)) " "$JSON_FILE" "$TOKEN")

curl -s -X POST https://www.liuxue.online/api/ielts
-H 'Content-Type: application/json'
-d "$PAYLOAD"

text

Ssd 3

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The batch-import workflow promotes automatic scanning of multiple broad areas of the user's computer to locate review files. This is risky because it normalizes wide filesystem discovery in a study skill, potentially exposing unrelated documents, filenames, or synchronized cloud content far beyond the least-privilege needed for the task.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

bash
TOKEN=$(cat ~/.ielts-tuyaya-token | python3 -c "import json,sys; print(json.load(sys.stdin)['token'])")
curl -s 'https://www.liuxue.online/api/ielts' -H 'Content-Type: application/json' \
  -d "{\"action\":\"getReviews\",\"token\":\"$TOKEN\",\"book\":<BOOK>,\"test\":<TEST>}" \
  | python3 -c "import json,sys; d=json.load(sys.stdin); recs=[r for r in d.get('data',[]) if r['book']==<BOOK> and r['test']==<TEST>]; print('✅ 已入库篇目:', [(r['passage'], r['score'], r['total']) for r in recs])"

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The matcher includes very broad terms such as 'IELTS', '复盘', and '错题分析', so normal educational requests can silently trigger the hook. This increases the chance of unexpected code execution and makes exploitation easier because an attacker only needs to induce a matching phrase rather than a deliberate command.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/setup-client-mode.sh (reported line 167)May include surrounding context.

sh
# ──────────────────────────── 服务端二次校验 ────────────────────────────
echo ""
echo "🔍 校验 token 有效性..."
RESP=$(curl -s -X POST "$API_BASE" \
  -H 'Content-Type: application/json' \
  -d "{\"action\":\"getUserInfo\",\"token\":\"$TOKEN\"}")

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README explicitly states '纯离线模式' and '不再依赖任何远程 API', which communicates a local-only scope. However, the same document describes opening a browser to liuxue.online for OAuth-style authorization and importing/uploading review data to the web system, so the declared behavior and actual documented operations are inconsistent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

A broad trigger like '帮我复盘' can cause the skill to activate during ordinary conversation without clear user intent, increasing the chance of unintended processing, file generation, or downstream upload/auth flows. In an agent environment with side effects, ambiguous invocation raises the risk of accidental data handling and overbroad task execution.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The stated intent for the skill is that structured JSON is deployed to the server and rendered by review.html, with 'No standalone HTML generation needed.' In contrast, the README presents local review HTML generation as a standard artifact and even describes HTML templates and browser viewing as primary workflow components, which directly conflicts with that intent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill exercises broad capabilities—shell, filesystem access, environment-variable access, and network transmission—but does not declare an explicit tool scope or permissions boundary. That makes it easier for the skill to invoke powerful operations implicitly, reducing user visibility and increasing the chance of overreach or misuse if the trigger fires unexpectedly.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/check-update.js:60