Back to skill

Security audit

拾遗 · 通用备考错题追踪(shiyi-study-tracker)

Security checks for vulnerabilities and agentic risk

Overview

This skill appears purpose-built for exam mistake tracking, but it retains sensitive screenshot/study data and exports it with several under-scoped safety issues users should review before installing.

Install only if you are comfortable with the skill saving exam text, annotations, and screenshots under ~/.openclaw/skills/shiyi and using your configured vision model to process images. Avoid sending screenshots with personal/account details, review exported spreadsheets before sharing them, and consider fixing the export sanitization, tag validation, temp-file handling, dependency pinning, and broad trigger phrases before using it on shared machines or sensitive materials.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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 (4)

T02 · Agent Memory Poisoning

Warning
Location
scripts/parse_input.js:73
Finding

Persistent Prompt Injection Through Stored Model-Generated Tags

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/export_xlsx.js:112
Finding

Spreadsheet Formula Injection in Exported XLSX Files

Content
View full analysis
[ q.date ?? '', (q.exam_name || q.exam) ?? '', q.section ?? '', q.question_type ?? '', q.knowledge_point ?? '', q.error_reason ?? '', q.question_text ?? '', q.visual_description ?? '', q.answer ?? '', q.user_annotation ?? '', Array.isArray(q.keywords) ? q.keywords.join('、') : '', q.status ?? '待二刷', q.source ?? '', '', ]); ``` ```python # Generated by scripts/export_xlsx.js:65-68 for ri, row in enumerate(wrong_rows, 2): for ci, val in enumerate(row, 1): cell = ws.cell(row=ri, column=ci, value=val) cell.alignment = Alignment(vertical="center", wrap_text=(ci in [7,8,10])) ``` ### Technical Analysis Question fields originating from user messages, captions, screenshots, and multimodal model output are copied into XLSX cells without neutralizing formula syntax. When OpenPyXL receives a string beginning with `=`, it can serialize the value as a spreadsheet formula rather than a literal string. The formula may execute when a user opens the exported workbook in a compatible spreadsheet application. This issue is especially relevant to `question_text`, `visual_description`, `user_annotation`, tag fields, and other values that can contain attacker-controlled text. ### Attack Path 1. An attacker causes a stored question field to begin with a spreadsheet formula, such as a hyperlink formula. 2. The record is saved in `wrong_questions.json`. 3. The user invokes the XLSX export operation. 4. `exportXlsx()` copies the field into `wrongRows` without sanitization. 5. The generated Python script passes the ...[truncated 792 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/export_xlsx.js:150
Finding

Path Traversal and Invalid Worksheet Name Through Export Section Filter

Content
View full analysis
a.startsWith('--section=')); const daysArg = process.argv.find(a => a.startsWith('--days=')); const sectionFilter = sectionArg ? sectionArg.split('=')[1] : null; const daysFilter = daysArg ? parseInt(daysArg.split('=')[1]) : null; ``` ### Technical Analysis The section filter is accepted from free-form message text or a command-line argument and then embedded directly into both an output filename and an Excel worksheet name. No validation removes path separators, traversal components, reserved filename characters, or Excel worksheet metacharacters. There is also no post-construction verification that the resolved output path remains inside `OUT_DIR`. A filter containing separators and traversal components can normalize outside the intended export directory when sufficient parent components are supplied and the target path is writab ...[truncated 1447 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/update_daily.js:62
Finding

Path Traversal Through Unvalidated Daily Record Date

Content
View full analysis
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (24)

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 · .gitignore (reported line 5)May include surrounding context.

text
data/
config.json
*.xlsx
.env
.DS_Store
*.log

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents the skill as a full-featured exam mistake-management tool centered on screenshot recognition and review workflows. The supplied code chunk does not implement those core capabilities. Instead, it performs a setup flow: sending a welcome prompt, asking for the exam type, resolving/storing an exam key, and handling later reconfiguration via '换考试'. While exam selection could be a supporting part of the broader skill, this chunk's actual behavior is materially narrower than the declared purpose and introduces local file storage that is not mentioned in the declared permissions. Therefore this code chunk does not accurately represent the advertised functionality on its own.

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

md
| `scripts/tag_library.js` | 标签词库读写与统计 |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `scripts/update_daily.js` | 写入错题和每日记录 |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `scripts/export_xlsx.js` | 导出 Excel(含筛选和截图嵌入) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `scripts/review_reminder.js` | 二刷提醒和自评处理 |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `scripts/daily_summary.js` | 每日定时总结 |

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README says '安装后发任意消息' ('after installation, send any message'), which makes the trigger condition extremely broad and likely to overlap with ordinary conversation. It does not define clear boundaries for when the skill should activate versus ignore unrelated messages.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly describes persistent local storage of wrong-question records, daily logs, backups, and exports, but does not warn users that screenshots and text may contain sensitive educational or personal data. In a messaging-integrated skill, silent retention and export of user-submitted content increases privacy risk, especially on shared hosts or devices where exported files and backups may be accessible to others.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger list includes broad everyday phrases such as '记得' and '不记得', which can cause the skill to activate unintentionally during unrelated conversations. Because the skill handles study records and file-backed state, accidental invocation can lead to unintended data writes, state changes, or confusing exports/reminders.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill describes screenshot recognition, persistent storage, reminders, and export behavior without clearly informing users what personal study data is collected, where it is stored, how long it is retained, or when it is exported. Since screenshots and wrong-question logs may contain sensitive personal or educational content, lack of transparent notice increases privacy and consent risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code decodes base64 screenshots and writes them as JPG files into the system temp directory before embedding them into the spreadsheet. These files contain sensitive study content and may remain accessible to other local users, backup tools, or forensic recovery if cleanup fails, so this is a real privacy/security weakness even though the files are later deleted on a best-effort basis.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill generates a temporary Python script, writes it to disk, and runs it via execFile. This combines file creation with subprocess execution, but the only visible log appears after completion, so users are not warned beforehand that code will be written and executed locally.

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 prompts instruct the user entirely in Chinese and explicitly tell them to send the exam name, without offering any language choice or opt-in. This is a language/locale policy concern because the skill appears to assume a specific language for all users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The confirmation and usage messages are also entirely in Chinese and do not provide any alternative locale or explain that the skill is region- or language-specific. This continues the language policy issue beyond the initial welcome prompt.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code sends user-provided image content and captions to an external vision-capable agent via agentCall without any visible consent, warning, or minimization in this component. Because this skill processes screenshots of exam mistakes, the images can easily contain personal data, handwritten notes, account details, or other sensitive educational content, creating a privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The function returns raw_image_b64 in the parsed result object, which increases the chance that full image contents are retained, logged, stored, or forwarded beyond the immediate OCR task. In this skill context, screenshots of study materials may also include personal notes or metadata, so retaining the raw image materially expands exposure if downstream storage, export, or logging occurs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This file contains natural-language prompts and comments that assume Chinese as the operating language, but there is no indication that users can opt into another language or that the skill is intentionally region-specific. Under the language/locale policy, forcing a specific language without user choice can be a policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The description is written entirely in Chinese, which can indicate a fixed language expectation for the skill. In this manifest there is no accompanying note that the skill is region-specific or that users may choose another language, so it may conflict with a language/locale choice policy.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The dependency xlsx is specified with a caret range, which allows future compatible versions to be installed implicitly. Because this package family has had multiple security advisories, leaving the version range open increases supply-chain risk and makes builds non-reproducible, especially for a skill that imports user-provided screenshots/data and exports files.

Content

Scanner excerpt · package.json (reported line 19)May include surrounding context.

json
"author": "",
  "license": "MIT",
  "engines": { "node": ">=18" },
  "dependencies": { "xlsx": "^0.18.5" },
  "optionalDependencies": { "sharp": "^0.33.0" },
  "scripts": {
    "export":         "node scripts/export_xlsx.js",

Unverifiable Dependency: xlsx has 5 known advisory(ies) (CVE-2021-32012 (Denial of Service in SheetJS Pro); CVE-2023-30533 (Prototype Pollution in sheetJS); CVE-2024-22363 (SheetJS Regular Expression Denial of Service (ReDoS)) +2 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The manifest includes xlsx, a package with several published advisories, but the version is not pinned, so it is unclear whether deployed installs are affected. In this skill's context, spreadsheet export from potentially user-influenced study data increases the relevance of parser/serialization bugs such as prototype pollution or denial of service.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
83% confidence
Finding

The optional dependency sharp is also specified with a caret range, allowing unreviewed patch/minor updates at install time. Although optional dependencies may not always be installed, if this image-processing library is present it may process user-supplied images, so uncontrolled version drift creates unnecessary supply-chain exposure.

Content

Scanner excerpt · package.json (reported line 20)May include surrounding context.

json
"license": "MIT",
  "engines": { "node": ">=18" },
  "dependencies": { "xlsx": "^0.18.5" },
  "optionalDependencies": { "sharp": "^0.33.0" },
  "scripts": {
    "export":         "node scripts/export_xlsx.js",
    "export:pending": "node scripts/export_xlsx.js --pending-only",

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code persists the user's exam choice to a config file in the home directory, but the user-facing onboarding messages do not disclose that this information will be stored locally. For a code file, persistent file writes affecting user data should have some visible warning, confirmation, or explanatory notice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file-level description is written entirely in Chinese, and the rest of the user-facing comments and defaults in the file follow the same language assumption. Under the stated policy, forcing a specific language without user opt-in or a documented region-specific justification is a natural-language policy issue.

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/export_xlsx.js:26