Back to skill

Security audit

BaZi Insight Report - Cantian AI

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for report checkout, but its status lookup can expose report status and a download-page URL from only a profile ID with unclear ownership checks.

Review this skill before installing. It sends report inputs and profile IDs to Cantian services and creates payment links, so only use it when the user has clearly asked to buy or check a report. Treat profile IDs like private access tokens, and prefer a version that requires explicit consent before checkout and stronger ownership/payment validation for status and download links.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/getReport.ts:59
Finding

Unauthenticated Report Lookup and Unreliable Payment Authorization

Content
View full analysis
( `${FIXED_API_BASE}/reports/search`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ filter: { profileIds: { $in: [profileId], }, }, pagination: { offset: 0, limit: 50, }, }), }, timeoutMs, ); } ``` ```ts async function getProfilePaidStatus(profileId: string, timeoutMs: number): Promise { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); try { const response = await fetch(`${FIXED_API_BASE}/profiles/${encodeURIComponent(profileId)}`, { method: "GET", signal: controller.signal, }); const text = await response.text(); let parsed: unknown = null; if (text) { try { parsed = JSON.parse(text); } catch { fail(`Get profile response is not valid JSON. Status=${response.status}, body=${text}`); } } if (!parsed || typeof parsed !== "object") { fail("Get profile returned empty or invalid JSON payload."); } const result = parsed as { code?: unknown; message?: unknown; msg?: unknown; error?: unknown; errorMessage?: unknown; data?: GetProfileData; }; if (typeof result.code !== "number") { fail(`Get profile returned invalid business code. Status=${response.status}, body=${text}`); } if (result.code === 1) { return true; } if (result.code === 40 ...[truncated 3797 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:23
Finding

Unpinned Runtime Fallback Dependency

Content
View full analysis
Remediation
View remediation
``` 2. Commit the generated lockfile and use `npm ci` for reproducible installations. 3. Review and update dependencies through a controlled process with vulnerability and provenance checks. 4. Use `npm ci --ignore-scripts` where package lifecycle scripts are not required. 5. Prefer the dependency-free Node.js execution path when the supported runtime is available. 6. Document the expected package integrity and periodically audit direct and transitive dependencies. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding

The code clearly supports the 'place order' portion of the description: it accepts report type, birth data, gender, locale, and email; builds a profile payload; and POSTs to /orders/create-anonymous-checkout to obtain a checkout session and pay URL. However, the declared purpose also says the skill handles progress tracking, status checks, and returning a download page when ready. None of those behaviors appear in this code chunk. This is a material description-behavior mismatch because the described skill is broader than the implemented functionality shown here.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The implementation is only a report-status lookup utility, not a checkout skill. It queries an existing profile and existing reports, then emits whether the profile is paid, whether a report is ready, and a constructed download page URL. There is no code for creating an order, selecting a report to purchase, processing checkout, or otherwise handling the 'buy report' portion of the declared purpose. Additionally, the returned downloadPageUrl is constructed whenever the profile is considered paid, not strictly only when the report is ready, which differs from the description's 'return download page when ready' behavior. The progress-tracking part is partially aligned, but the overall declared description materially overstates the code's functionality.

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

md
- 执行目录:在 skill 根目录(`SKILL.md` 所在目录)运行以下命令

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- 执行目录:在 skill 根目录(`SKILL.md` 所在目录)运行以下命令

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/getReport.ts`:按 `profileId` 查询报告状态

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/getReport.ts`:按 `profileId` 查询报告状态

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/getReport.ts`:按 `profileId` 查询报告状态

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/getReport.ts`:按 `profileId` 查询报告状态

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/getReport.ts`:按 `profileId` 查询报告状态

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs the agent to run scripts that create checkout sessions and query report status, which implies outbound network/API access, but it declares no explicit tool scope or allowed-tools restrictions. Missing permission boundaries increases the risk of over-privileged execution and makes it harder to audit or constrain what external actions the skill may perform.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger guidance includes broad, everyday phrases like '我要' and '我想', which can cause the skill to activate on ambiguous user messages and initiate a payment/order flow prematurely. In a commerce context, overly broad activation boundaries are risky because they can lead to unintended checkout creation, unnecessary collection of personal data, or user confusion around consent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The invocation rules explicitly allow inferring purchase intent even when the user does not clearly say 'buy', which weakens activation boundaries for a paid transaction flow. In this context, the skill handles email, birth data, gender, and payment-link generation, so mistaken activation has elevated privacy and transactional risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The locale normalization logic returns 'zh' when no locale is provided and also falls back to 'zh' for any unsupported locale. This imposes a specific language choice without user opt-in, which matches the policy-violation category for forced language or locale behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code assigns a default locale of "zh" when the user does not provide --locale, which forces a specific language choice automatically. The policy allows fixed locale behavior only when the user is given a choice or the constraint is clearly justified; neither is evident here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script collects and transmits highly sensitive personal data, including email, birth date/time, gender, and optional location/nickname, to a remote API endpoint. While sending such data may be functionally necessary for the service, the code provides no explicit privacy notice, consent checkpoint, or minimization controls, which creates a real privacy/security risk if users do not understand what data leaves their environment or how it is used.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The output hard-codes a default locale of "zh" when a report locale is unavailable, which imposes a specific language choice on the user. The file does not offer locale selection or explain why Chinese is required, so this appears to violate the language/locale policy for natural-language behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code sends the provided profileId to external endpoints via a POST search request and a GET profile lookup, but the script contains no warning, prompt, or comment disclosing that user-supplied identifier data will be transmitted over the network. For a code file, network calls that transmit user or system data should have some visible disclosure unless clearly covered elsewhere in documentation, which is not evident in this file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.