Back to skill

Security audit

Taxi Expense

Security checks for vulnerabilities and agentic risk

Overview

This taxi expense skill has a legitimate purpose, but it should be reviewed because it stores sensitive trip data and screenshots while its destination redaction can fail open and its setup pulls unverified dependencies and OCR data.

Install only if you are comfortable with the skill creating local records of taxi dates, times, locations, amounts, screenshots, and spreadsheets. Review generated screenshots and Excel files before sharing, especially because destination masking can silently fail. Run setup without elevated privileges and prefer updated, pinned dependencies plus verified OCR model files before 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

Error
Location
scripts/process.js:122
Finding

Destination Image Redaction Fails Open

Content
View full analysis
{ const t = l.text.replace(/\s+/g, ''); return (t.match(/终[点炭]/)) && l.bbox.y0 > cardTop && l.bbox.y0 < timeLine.bbox.y0; }); let mosaicRegions = []; if (destLine) { const destWords = ocrData.words.filter(w => w.bbox.y0 >= destLine.bbox.y0 - 5 && w.bbox.y1 <= destLine.bbox.y1 + 5 && !['终', '点', '炭', ':', ':'].includes(w.text) ); if (destWords.length >= 2) { const first = destWords[0]; const last = destWords[destWords.length - 1]; mosaicRegions.push({ left: first.bbox.x1 + 3, top: destLine.bbox.y0 - 2, width: Math.max(0, last.bbox.x0 - first.bbox.x1 - 6), height: destLine.bbox.y1 - destLine.bbox.y0 + 4, }); } } const imgMeta = await sharp(srcImg).metadata(); const cropTop = Math.max(0, cardTop); const cropHeight = Math.min(imgMeta.height - cropTop, cardBottom - cardTop); // Build composite overlay list for single pipeline let overlays = []; for (const reg of mosaicRegions) { const relTop = reg.top - cropTop; if (reg.width > 0 && reg.height > 0) { try { const block = await sharp({ create: { width: reg.width, height: reg.height, channels: 3, background: { r: 255, g: 255, b: 255 } } }).png().toBuffer(); overlays.push({ input: block, left: reg.left, top: relTop }); console.log(` [mosaic] block: ${reg.left},${relTop} ${reg.width}x${reg.height}`); } catch (e) { console.warn(' Mosaic failed for', order.date, e.message); } } } // Single pipeline: crop + composite + save let pipeline = sharp(srcImg).extract({ left: 0, top: cropTop, width: imgMeta.width, height: cropHeight }); if (overlays.length > 0) { pipeline = pipeline.composite(overlays); } ...[truncated 3223 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/setup.sh:19
Finding

Non-Reproducible Dependency and OCR Model Installation

Content
View full analysis
/dev/null npm install tesseract.js@4 sharp exceljs --save --silent 2>&1 | tail -3 # 下载 Tesseract 训练数据 PROXY="${http_proxy:-$HTTP_PROXY}" PROXY_FLAG="" [ -n "$PROXY" ] && PROXY_FLAG="-x $PROXY" for lang in chi_sim eng; do if [ -f "$TESSDATA_DIR/${lang}.traineddata" ]; then echo "✅ ${lang}.traineddata 已存在" continue fi # 尝试从本地已有目录复制 if [ -f "/tmp/tessdata/${lang}.traineddata" ]; then echo "📋 复制 ${lang}.traineddata from /tmp/tessdata/" cp "/tmp/tessdata/${lang}.traineddata" "$TESSDATA_DIR/" continue fi # 尝试下载 echo "📥 下载 ${lang}.traineddata ..." GZ_FILE="$TESSDATA_DIR/${lang}.traineddata.gz" curl -sL $PROXY_FLAG "https://github.com/tesseract-ocr/tessdata/raw/main/${lang}.traineddata.gz" -o "$GZ_FILE" # 检查是否为有效 gzip 文件 if file "$GZ_FILE" | grep -q "gzip"; then gunzip -c "$GZ_FILE" > "$TESSDATA_DIR/${lang}.traineddata" rm -f "$GZ_FILE" echo "✅ ${lang}.traineddata 解压完成" else echo "❌ ${lang}.traineddata 下载失败(非 gzip 格式)" echo " 请手动复制: cp /your/path/${lang}.traineddata $TESSDATA_DIR/" fi done ``` From `deps/package.json`: ```json "dependencies": { "exceljs": "^4.4.0", "sharp": "^0.34.5", "tesseract.js": "^4.1.4" } ``` ### Technical Analysis The project contains a lockfile with npm registry URLs and integrity hashes, but setup does not enforce an immutable installation through `npm ci`. Instead, it invokes `npm install` with broad package specifications: - `tesseract.js@4` allows different releases within major version 4. - `sharp` and `exceljs` are installed without versions in the setup command. - The manifest uses caret ranges, allowing compatible later releases. - In ...[truncated 2741 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (19)

Known Vulnerable Dependency: brace-expansion==1.1.13 — 3 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro); CVE-2026-69152 (brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-1)

High
Category
Supply Chain
Confidence
93% confidence
Finding

The lockfile includes brace-expansion 1.1.13, which is flagged for denial-of-service issues caused by pathological brace patterns that can trigger excessive CPU or memory consumption. In this skill, the package is a transitive dependency used for glob/minimatch behavior rather than a deliberately risky feature, but if attacker-controlled patterns ever reach that code path, it can still cause process instability or hangs.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: brace-expansion==2.0.3 — 3 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro); CVE-2026-69152 (brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-1)

High
Category
Supply Chain
Confidence
91% confidence
Finding

The lockfile also contains brace-expansion 2.0.3, which is similarly reported vulnerable to resource-exhaustion conditions from crafted expansion input. Although this is only a transitive package and there is no evidence of malicious inclusion, a skill that processes files and archives can increase the chance that globbing or archive-related code paths are exercised with untrusted filenames or patterns.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: sharp==0.34.5 — 2 advisory(ies): GHSA-f88m-g3jw-g9cj (sharp inherited vulnerabilities in libvips: CVE-2026-33327, CVE-2026-33328, CVE-); GHSA-rgj7-g3m4-5g8c (sharp: Vulnerabilities in libheif: GHSA-g89c-p67h-r497 and GHSA-2jg2-4ch7-h545)

High
Category
Supply Chain
Confidence
95% confidence
Finding

sharp 0.34.5 is directly relevant to this skill because the skill processes user-supplied taxi receipt screenshots, and sharp bundles image-processing components that may inherit vulnerabilities from native codecs such as libvips/libheif. If a crafted image triggers one of those flaws, the result could range from denial of service to memory corruption in a native library, making this materially more dangerous than an unused dependency.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: tmp==0.2.5 — 1 advisory(ies): CVE-2026-44705 (tmp has Path Traversal via unsanitized prefix/postfix that enables directory esc)

High
Category
Supply Chain
Confidence
86% confidence
Finding

tmp 0.2.5 is present as an exceljs dependency and is reported vulnerable to path traversal via unsanitized prefix/postfix handling. In this skill, temporary-file creation may be reachable during Excel generation, so if any attacker-controlled values are incorporated into temp naming or paths by the application or upstream library, files could potentially be created in unintended locations.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: sharp==0.34.5 — 2 advisory(ies): GHSA-f88m-g3jw-g9cj (sharp inherited vulnerabilities in libvips: CVE-2026-33327, CVE-2026-33328, CVE-); GHSA-rgj7-g3m4-5g8c (sharp: Vulnerabilities in libheif: GHSA-g89c-p67h-r497 and GHSA-2jg2-4ch7-h545)

High
Category
Supply Chain
Confidence
98% confidence
Finding

The skill depends on sharp 0.34.5, which is reported to include vulnerable native image codec dependencies (libvips/libheif). Because this skill explicitly processes taxi receipt screenshots supplied as input, a crafted image could trigger memory corruption, denial of service, or potentially code execution in the image parsing stack.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The conversational trigger word “处理” is overly generic and can easily appear in normal chat, making unintended activation plausible. In this skill, unintended activation could cause processing of user-provided screenshots containing sensitive travel and location data, leading to privacy exposure or accidental file generation without clear user intent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill invokes shell commands (bash setup.sh, node process.js, and openclaw message send) but does not declare any explicit tool scope or allowed-tools restrictions. This creates a permission-boundary weakness: an agent may execute shell-capable behavior without a clearly documented least-privilege contract, increasing the chance of unintended command execution or misuse if the skill is auto-selected.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation phrase 'When user sends taxi order screenshots' is broad and may trigger on any image that appears related, without requiring explicit user consent to run OCR, persist data, or generate reimbursement files. In a context handling personal travel screenshots and local file writes, overly permissive activation increases the risk of processing sensitive data unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill stores screenshots and extracted ride data in persistent local paths, but the description does not clearly warn users that their images, travel history, addresses, and expense records will be retained on disk. Because taxi receipts contain sensitive personal and location data, silent persistence materially increases privacy and data-handling risk even if the primary purpose is legitimate reimbursement processing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script reads existing order history from taxi_data.json and later writes merged order data back to that file, creating a persistent record of travel dates, times, locations, and amounts. Although file output occurs, there is no confirmation prompt, disclosure comment, or other user-facing warning that personal trip data will be stored locally beyond the generated terminal logs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script saves processed screenshots to the screenshots directory, and even with partial mosaic handling they still contain order-related information such as dates, amounts, and route context. There is no explicit warning or confirmation that image files derived from user-provided screenshots will be created and retained on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code creates monthly Excel files and embeds screenshot images into them, producing shareable documents that may contain sensitive travel and expense information. While the file path is logged after creation, there is no prior disclosure or confirmation that such consolidated records will be generated and stored.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
74% confidence
Finding

该 README 全文以中文指令、字段和交互短语描述技能使用方式,包括对话中的固定表达“说‘处理’即可”,但未向用户提供语言/locale 选择,也未说明该技能为何必须限定中文。按照语言/地区策略,强制特定语言而无用户选择可能构成自然语言政策问题。

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: uuid==8.3.2 — 1 advisory(ies): CVE-2026-41907 (uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided)

Low
Category
Supply Chain
Confidence
78% confidence
Finding

uuid 8.3.2 is reported for a missing buffer bounds check in certain hash-based UUID variants when a buffer argument is supplied. This is a real dependency risk, but in this skill context it is likely low impact because it is transitive via exceljs and there is no evidence the application exposes attacker-controlled access to the affected API shape.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
89% confidence
Finding

The dependency uses a caret range (^4.4.0), which permits automatic installation of newer minor/patch releases rather than an exact vetted version. This increases supply-chain risk and can introduce unexpected behavior or newly published malicious/broken releases into the build without explicit review.

Content

Scanner excerpt · deps/package.json (reported line 14)May include surrounding context.

json
"license": "ISC",
  "type": "commonjs",
  "dependencies": {
    "exceljs": "^4.4.0",
    "sharp": "^0.34.5",
    "tesseract.js": "^4.1.4"
  }

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The sharp dependency is specified with a caret range (^0.34.5), allowing resolution to future patch/minor releases without explicit approval. In a package that processes untrusted image inputs, dependency drift is a meaningful supply-chain concern because parsing libraries are security-sensitive.

Content

Scanner excerpt · deps/package.json (reported line 15)May include surrounding context.

json
"type": "commonjs",
  "dependencies": {
    "exceljs": "^4.4.0",
    "sharp": "^0.34.5",
    "tesseract.js": "^4.1.4"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

The tesseract.js dependency is unpinned via a caret range (^4.1.4), so builds may pull different releases over time. This is a supply-chain weakness because OCR libraries are complex dependencies and should be upgraded only through explicit review and reproducible builds.

Content

Scanner excerpt · deps/package.json (reported line 16)May include surrounding context.

json
"dependencies": {
    "exceljs": "^4.4.0",
    "sharp": "^0.34.5",
    "tesseract.js": "^4.1.4"
  }
}

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script fixes OCR recognition to chi_sim+eng, which imposes a specific language/locale configuration without exposing any user choice. Under the policy, forcing a language or locale without opt-in is a natural-language policy concern unless it is clearly documented as a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This shell script includes natural-language comments and usage guidance in Chinese, and later emits Chinese user-facing status/error messages, but it does not provide any opt-in or alternative language. That can violate language/locale policy when users are not explicitly offered a language choice.

Content

No source excerpt is available for this finding.