Back to skill

Security audit

AI Customer Service KB Builder

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent FAQ-builder, but its website-scraping and CSV-export features are under-scoped enough that users should review it before installing.

Install only if you are comfortable with a local CLI that reads FAQ files, writes output files, and can fetch any URL it is given. Do not let untrusted users or prompts choose scrape URLs, especially in cloud or corporate networks, and treat CSV exports from scraped or third-party FAQ content as untrusted spreadsheet files.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
kb-builder.js:108
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis
{ const client = url.startsWith('https') ? https : http; client.get(url, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { // Simple HTML text extraction const text = data .replace(/]*>[\s\S]*?<\/script>/gi, '') .replace(/]*>[\s\S]*?<\/style>/gi, '') .replace(/<[^>]+>/g, ' ') .replace(/ /g, ' ') .replace(/\s+/g, ' ') .trim(); resolve(text); }); }).on('error', reject); }); } ``` The user-controlled URL reaches this function through the `scrape` command: ```javascript const url = getArg('--url'); const outputPath = getArg('--output') || './kb.json'; if (!url) { console.error('Error: --url is required'); process.exit(1); } console.log(`Scraping FAQ from ${url}...`); const text = await scrapeFromURL(url); const entries = parseFAQ(text); ``` ### Technical Analysis The application performs an outbound HTTP or HTTPS request to a URL supplied through the `--url` argument. It does not validate the destination hostname, port, or resolved IP address and does not reject loopback, private, link-local, or other reserved address ranges. Consequently, the process can be instructed to connect to resources that are inaccessible to the external attacker but accessible from the host running the Skill. Potential targets include: - Services bound to `127.0.0.1` or `::1` - Services on private network ranges - Container or orchestration control endpoints - Link-local cloud metadata services - Unauthenticated internal administration interfaces The response is converted to text, parsed as FAQ conte ...[truncated 1375 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
kb-builder.js:108
Finding

Unbounded Remote Response Buffering Enables Resource Exhaustion

Content
View full analysis
{ const client = url.startsWith('https') ? https : http; client.get(url, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { // Simple HTML text extraction const text = data .replace(/]*>[\s\S]*?<\/script>/gi, '') .replace(/]*>[\s\S]*?<\/style>/gi, '') .replace(/<[^>]+>/g, ' ') .replace(/ /g, ' ') .replace(/\s+/g, ' ') .trim(); resolve(text); }); }).on('error', reject); }); } ``` ### Technical Analysis The scraper appends every received chunk to a JavaScript string without imposing a maximum response size. It also does not configure connection, header, or body-read timeouts. A remote server can therefore send an extremely large response, stream data indefinitely, or transmit data slowly enough to retain process resources for an extended period. Repeated string concatenation and subsequent regular-expression processing can consume substantial memory and CPU. If Node.js reaches its heap limit, the process may terminate. The application also does not validate the HTTP status or content type before buffering and processing the body. ### Attack Path 1. An attacker controls or identifies an HTTP endpoint that returns a very large body or streams data indefinitely. 2. The attacker causes the Skill to execute `scrape --url` against that endpoint. 3. Each response chunk is appended to the in-memory `data` string with no byte limit. 4. The process continues allocating memory until the response ends or the Node.js heap is exhausted. 5. If the response eventually ends, several ...[truncated 581 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
kb-builder.js:168
Finding

Unsafe CSV Export Permits Spreadsheet Formula Injection

Content
View full analysis
`"${e.id}","${e.question}","${e.answer}","${e.keywords.join(';')}","${e.category}"` )) .join('\n'); fs.writeFileSync(outputPath, csv, 'utf8'); break; ``` ### Technical Analysis Knowledge-base properties are inserted directly into quoted CSV cells. The implementation does not: - Escape embedded double quotes according to CSV rules - Neutralize values beginning with spreadsheet formula characters such as `=`, `+`, `-`, or `@` - Normalize control characters that may affect spreadsheet parsing The knowledge-base entries may originate from attacker-controlled FAQ documents or scraped websites. When the exported file is opened in spreadsheet software, a cell beginning with a formula marker may be interpreted as a formula rather than inert text. The exact behavior and available formula features depend on the spreadsheet application and its security settings. Potential formula payloads can cause external requests, expose spreadsheet data, or present deceptive links and content. Embedded quotes can additionally break the intended CSV column structure. ### Attack Path 1. An attacker places a formula-like value in a source FAQ question or answer, such as a value beginning with `=`. 2. A user extracts or scrapes that content into a knowledge base. 3. The user invokes the `export` command with `--format csv`. 4. `exportKB()` inserts the value into the CSV without formula neutralization or correct quote escaping. 5. A victim opens the generated CSV in spreadsheet software. 6. The spreadsheet may evaluate the cell as a formula, potentially causing external network interaction, data disclosure, or deceptive content. ### Impact Assessment The vuln ...[truncated 529 chars]
Remediation
View remediation
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (8)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The sample configuration hard-codes language: zh-CN and a Chinese fallback message, and the output schema later also fixes language to zh-CN. There is no accompanying note that other languages are supported or that Chinese is merely an example, which can violate language/locale choice policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The config sets the skill language to "zh-CN" with no indication that users can choose another language or opt in to this locale. The policy explicitly flags language or locale constraints when they are imposed without user choice or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The default configuration hard-codes language: 'zh-CN' and a Chinese-only fallback message, which imposes a specific language/locale policy on users. The file does not offer a language choice at runtime or explain why the locale restriction is necessary.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest declares a fixed language of "zh-CN", and the content is written exclusively in Simplified Chinese without any visible indication of user opt-in or that the skill is intentionally region-specific. Per policy, forcing a specific language/locale is a concern unless choice or clear justification is documented.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The keyword list for the return-policy FAQ includes very short fragments such as single-word or partial-word matches that can overlap with unrelated user inputs. In a retrieval or trigger-based assistant, this can cause unintended activation of the wrong entry, producing incorrect guidance and reducing the reliability of user-facing responses.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The payment FAQ uses broad partial keywords like short fragments of 'payment methods,' which are likely to match many unrelated finance or checkout questions. This can misroute users to a generic payment answer when they may be asking about billing failures, refunds, or other sensitive transaction topics.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The order-modification entry contains generic triggers such as '订单' and short partial forms that are common in many shopping conversations. In a skill that relies on keyword matching, this can cause the order-change response to override more appropriate order-status, cancellation, or shipping answers.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The example JSON schema presents language: zh-CN as the output value, reinforcing a Chinese-only default behavior. Without explicit opt-in or documentation of configurable locales, this suggests the skill is oriented to a single language by default.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.