Back to skill

Security audit

紫微斗数排盘解盘

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent local Chinese astrology chart helper, with privacy and input-hardening cautions but no evidence of hidden or malicious behavior.

Install only if you are comfortable providing birth time, gender, and location to a local astrology tool. Avoid saving real personal chart fixtures in shared repositories or synced folders, validate longitude values before use, and treat health, finance, and relationship readings as entertainment or reflection rather than professional advice.

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
zwds-cli/src/index.js:4
Finding

Unbounded Standard Input Can Cause Memory Exhaustion

Content
View full analysis

Vulnerability Details

File Location: zwds-cli/src/index.js, lines 4–7
Vulnerability Type: Uncontrolled resource consumption through unbounded input buffering
Risk Level: Medium

Vulnerable Code

javascript
async function readStdin() {
  const chunks = [];
  for await (const c of process.stdin) chunks.push(c);
  return Buffer.concat(chunks).toString("utf8");
}

Technical Analysis

The CLI reads the entire standard-input stream into an array without enforcing a maximum payload size. After retaining every input chunk, it calls Buffer.concat() and converts the resulting buffer to a UTF-8 string, creating additional memory allocations before JSON parsing or field validation occurs.

An attacker or untrusted caller who can invoke the CLI can supply an arbitrarily large stream. Memory consumption therefore grows with the input size and may exceed the Node.js heap or available system memory.

Attack Path

  1. The attacker invokes node src/index.js directly or through an application that exposes the CLI.
  2. The attacker streams an extremely large payload to standard input.
  3. readStdin() retains every chunk in memory without a byte limit.
  4. Buffer.concat() allocates a combined buffer, and toString("utf8") creates another representation.
  5. The process becomes unresponsive or terminates because of memory exhaustion before JSON validation is reached.

Impact Assessment

Successful exploitation can terminate or stall the chart-generation process. If the CLI runs inside a shared Agent, worker, or service process without strict resource isolation, the impact may extend to other requests handled by that process or host.

The vulnerability does not provide code execution, additional privileges, filesystem access, or data disclosure. Its confirmed scope is local denial of service against the invoking process and potentially its hosting service.

Remediation
View remediation

Remediation Suggestions

Enforce a small, documented maximum input size before retaining additional chunks. Stop reading and reject the request immediately when the limit is exceeded.

For example:

javascript
async function readStdin(maxBytes = 64 * 1024) {
  const chunks = [];
  let totalBytes = 0;

  for await (const chunk of process.stdin) {
    totalBytes += chunk.length;

    if (totalBytes > maxBytes) {
      throw new Error(`stdin payload exceeds ${maxBytes} bytes`);
    }

    chunks.push(chunk);
  }

  return Buffer.concat(chunks, totalBytes).toString("utf8");
}

Additional hardening should include:

  • Apply request-size limits in any wrapper or service that launches the CLI.
  • Run the process with memory and execution-time limits.
  • Keep error responses generic and machine-readable.
  • Add a regression test that submits input above the configured limit and verifies prompt rejection.

T09 · Insecure Skill Coding Practices

Warning
Location
zwds-cli/src/longitudeLookup.js:27
Finding

Unrestricted Longitude Causes CPU-Exhaustion Loop

Content
View full analysis

Vulnerability Details

File Location: zwds-cli/src/longitudeLookup.js, lines 27–32; zwds-cli/src/solarTime.js, lines 50–54
Vulnerability Type: Improper numeric range validation leading to algorithmic denial of service
Risk Level: Medium

Vulnerable Code

From zwds-cli/src/longitudeLookup.js:

javascript
function resolveLongitude(birthPlace, explicitLongitude) {
  if (explicitLongitude != null && explicitLongitude !== "") {
    const n = Number(explicitLongitude);
    if (Number.isFinite(n)) {
      return { longitude: n, source: "input", matched: null };
    }
  }

From zwds-cli/src/solarTime.js:

javascript
const longitudeCorrection = (longitude - 120) * 4;
let correctedMinutes = minutes - dstCorrection + longitudeCorrection;

while (correctedMinutes < 0) correctedMinutes += 24 * 60;
while (correctedMinutes >= 24 * 60) correctedMinutes -= 24 * 60;

Technical Analysis

Explicit longitude input is accepted whenever conversion produces a finite JavaScript number. The code does not enforce the geographically valid longitude range of -180 through 180.

The solar-time calculation converts longitude into a minute offset and normalizes that value by repeatedly adding or subtracting 1,440 minutes. This algorithm is proportional to the magnitude of the supplied longitude. A value such as 1e308 is finite and therefore accepted, but it requires an impractically large number of loop iterations during normalization.

Because the malicious input is very small, network or stdin size limits alone do not mitigate this issue.

Attack Path

  1. The attacker supplies an otherwise valid JSON request containing a birth place and a huge finite longitude, for example:
json
{
  "birth_time": "2000-08-16T06:00:00",
  "birth_place": "Shanghai",
  "gender": "female",
  "longitude": 1e308
}
  1. resolveLongitude() converts the longitude with Number() and accepts it because Number.isFinite(1e308) is true.
  2. Because `birth_pl ...[truncated 825 chars]
Remediation
View remediation

Remediation Suggestions

Validate explicit longitude as both finite and geographically valid:

javascript
const n = Number(explicitLongitude);

if (!Number.isFinite(n) || n < -180 || n > 180) {
  throw new Error("longitude must be a finite number between -180 and 180");
}

return { longitude: n, source: "input", matched: null };

Replace iterative time normalization with constant-time modulo arithmetic:

javascript
correctedMinutes =
  ((correctedMinutes % (24 * 60)) + (24 * 60)) % (24 * 60);

Additional hardening should include:

  • Reject invalid explicit longitude rather than silently falling back to a database or default value.
  • Validate latitude/longitude-style fields at the input boundary before performing calculations.
  • Add tests for 180, -180, out-of-range values, 1e308, Infinity, NaN, numeric strings, and malformed strings.
  • Apply an execution timeout in any service wrapper as defense in depth.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (15)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation description is triggered by several broad, common phrases such as '时辰' and '生辰八字', which can appear in ordinary conversation without a clear requirement that the user explicitly wants this astrology skill. Over-broad activation can cause the agent to invoke a highly specialized skill in unintended contexts, leading to irrelevant processing, privacy over-collection of birth data, or bypass of safer/default handling paths.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The fixture workflow explicitly instructs users to save birth time, gender, birth place, optional longitude, and the full generated chart output in reusable files, but provides no privacy warning, minimization guidance, or retention controls. Because this skill processes highly sensitive personal data tied to identity and profiling, storing it in fixtures increases the risk of accidental disclosure through source control, file sharing, backups, or workspace attachments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The user-facing instructions and descriptions in this file are entirely in Chinese, including operational guidance for adding, updating, and reading fixtures. There is no indication that the language requirement is optional, configurable, or justified by a region-specific constraint, which creates a natural-language policy concern under the language/locale rule.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This JSON fixture embeds human-readable titles, notes, place names, and domain values entirely in Chinese, including an instruction string at L0013 directing how the file should be used. For a general-purpose skill artifact, this constitutes a locale/language constraint with no visible opt-in, fallback, or justification that the file is intended only for a Chinese-language or region-specific workflow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The document title and all operational guidance are written exclusively in Chinese, which imposes a specific language on users. Under the policy, language constraints should either provide user choice or be explicitly justified as region-specific; this file does neither.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code creates directories and writes a JSON fixture containing the full input object and CLI output, which may include personal data such as birth place and birth time. Although the file header explains the script's purpose and the final console log reports the destination, there is no explicit user-facing warning that sensitive data will be persisted to disk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code sets language = "zh-CN" as the default, which forces a specific locale when the caller does not explicitly choose one. Under the policy, language or locale constraints should be user-selectable or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

Natural-language instructions, examples, and testing guidance are all presented in Chinese, and the file does not indicate that Chinese is optional or that the skill is intentionally region- or locale-specific. Under the stated policy, forcing a specific language without user opt-in can be a language/locale policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

Line L40 states that the language field defaults to zh-CN, which is a locale-specific behavior described in natural language. Under the policy, forcing a specific language or locale without user opt-in can be a violation unless the constraint is explicitly justified or users are given a choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This JSON file stores all geographic names exclusively in Chinese characters, which can impose a specific language/locale on downstream skill behavior if consumed directly for user-facing output. Because the file contains no accompanying indication of optional localization or user choice, it may conflict with a policy requiring language selection or opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

This JSON file contains only Chinese-language city names and administrative labels, with no accompanying indication that the skill is China-specific or that Chinese locale output is intentional. Under the policy rule for natural-language violations, forcing a specific language/locale without user opt-in can be problematic when the scope is not documented.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This JSON manifest-like data file contains location names exclusively in Chinese, which imposes a specific language/locale in the skill data without any visible opt-in or justification in the file itself. Under the policy rule for natural-language locale constraints, hard-coded language-specific content can be a policy concern when no user choice or explicit regional justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This JSON file consists entirely of Chinese place names and administrative labels, indicating a fixed language/locale presentation. For a skill artifact, forcing one locale without any documented opt-in or alternative can violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This JSON dataset includes multilingual natural-language values such as Chinese, English, and Japanese names in the same skill data file. Because the file provides no documented locale-selection policy or opt-in, it can contribute to language behavior that is fixed by the skill author rather than chosen by the user.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The top-level explanatory comment is written only in Chinese, which can constitute a language/locale policy issue when the skill does not offer any language choice or document that it is intentionally region-specific. This is the only natural-language content in the file and it constrains comprehension to a specific language audience.

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
zwds-cli/scripts/save-fixture.mjs:35

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
zwds-cli/test/golden.test.js:79