Back to skill

Security audit

Daily Bazi Analysis

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent as a Chinese BaZi daily-fortune tool, but it broadly auto-triggers and persistently stores or logs user-linked birth-chart data without clear opt-in, retention, or deletion controls.

Review before installing if users may ask generic scheduling questions or if personal data retention matters. Operators should require explicit consent before saving Four Pillars, provide review/delete controls, minimize logs, narrow activation to explicit BaZi intent, and run calendar imports with a fixed table name and low database privileges.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/import_bazi_calendar.py:101
Finding
SQL Injection Through an Unvalidated Table Identifier## Vulnerability Details **File Location**: `scripts/import_bazi_calendar.py`, lines 101-103, 111, and 132 **Vulnerability Type**: SQL injection in generated database statements **Risk Level**: Medium ### Vulnerable Code ```python def build_sql(records: List[Dict[str, str]], table: str) -> str: today = dt.datetime.now(dt.timezone.utc).isoformat() lines = [ "BEGIN;", f"CREATE TABLE IF NOT EXISTS {table} (", " date TEXT PRIMARY KEY,", " flow_year TEXT NOT NULL,", " flow_month TEXT NOT NULL,", " flow_day TEXT NOT NULL,", " source TEXT,", " updated_at TEXT", ");", ] for r in records: lines.extend( [ f"INSERT INTO {table} (date, flow_year, flow_month, flow_day, source, updated_at)", "VALUES (" + ", ".join( [ sql_quote(r["date"]), sql_quote(r["flow_year"]), sql_quote(r["flow_month"]), sql_quote(r["flow_day"]), sql_quote("xlsx_2026"), sql_quote(today), ] ) + ")", "ON CONFLICT(date) DO UPDATE SET", " flow_year=excluded.flow_year,", " flow_month=excluded.flow_month,", " flow_day=excluded.flow_day,", " source=excluded.source,", " updated_at=excluded.updated_at;", ] ) ``` ```python parser.add_argument( "--table", default="bazi_daily_calendar", help="Target table name", ) ``` ### Technical Analysis The caller-controlled `--table` argument is passed to `build_sql()` and interpolated directly into `CREATE TABLE` and `INSERT INTO` statements. The program does not restrict this argument to a valid SQL identifier or quote it using a database-specific identifier-quoting me ...[truncated 2118 chars]
Remediation
## Remediation Suggestions 1. **Remove unnecessary configurability.** The Skill requires the fixed `bazi_daily_calendar` table, so the safest design is to remove `--table` and use a constant: ```python TABLE_NAME = "bazi_daily_calendar" ``` 2. **If custom table names are required, apply a strict allowlist.** Permit only conventional unqualified SQL identifiers: ```python import re IDENTIFIER_RE = re.compile(r"[A-Za-z_][A-Za-z0-9_]*\Z") def validate_table_name(value: str) -> str: if not IDENTIFIER_RE.fullmatch(value): raise ValueError("Invalid table name") return value ``` Validate the argument before passing it to `build_sql()`: ```python table = validate_table_name(args.table) sql = build_sql(records, table) ``` 3. **Quote the validated identifier correctly.** Where supported, use the target database engine's identifier-quoting mechanism after validation. Do not use `sql_quote()`, because it creates string literals rather than quoted identifiers. 4. **Reject qualified or special identifiers unless explicitly required.** Do not allow dots, whitespace, comments, semicolons, quotes, brackets, or control characters. 5. **Apply least privilege to imports.** Run the import with a database account restricted to creating and updating only the intended calendar table. It should not be able to access unrelated application tables. 6. **Validate generated SQL before execution.** Administrative automation should verify that the output contains only the expected transaction, table creation, and upsert statements for the fixed table. 7. **Add negative tests.** Confirm rejection of inputs such as identifiers containing semicolons, SQL comments, quotes, whitespace, qualified names, or statement keywords.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description is for an interactive astrology/fortune-analysis skill with memory of user birth-chart data and date-based reasoning. The supplied code contains none of that logic. It is purely a command-line document conversion tool for extracting text from three classic PDFs into text/markdown reference files. Its inputs, outputs, runtime context, and primary purpose are materially different from the declared skill behavior, so this is a clear mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
声明描述的是一个面向终端用户的占卜/分析型技能,而代码只是一个数据预处理与导入工具。其主要功能是从 xlsx 提取日历字段并生成 SQL 建表与 upsert 语句,属于后台数据管道脚本,不是实际的“今日运势解读”能力实现。虽然导入的流年/流月/流日数据可能作为该技能的支撑数据,但当前代码块本身没有实现声明中的核心行为,因此属于明显不匹配。

Vague Triggers

High
Confidence
95% confidence
Finding
The trigger scope is explicitly broad enough to auto-activate on generic requests like whether today is suitable for doing something, even when the user did not ask for BaZi analysis. This can cause unexpected invocation, collection of sensitive profile data, and unsolicited astrological guidance in contexts where the user intended a different type of help.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill instructs collecting and persistently storing the user's Four Pillars in long-term memory without any user-facing privacy notice, retention disclosure, or consent step. Even if not highly regulated by itself, this is persistent personal profile data tied to identity and future inference, which creates privacy and trust risks if stored silently.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
Forcing a fallback timezone of Asia/Shanghai without user opt-in can produce incorrect date-based analysis for users elsewhere, and in this skill the date directly drives the result. While not a classic security exploit, it can lead to silent misprocessing of user data and inaccurate outputs tied to location assumptions.

Ssd 3

Medium
Confidence
94% confidence
Finding
The skill mandates persistent logging of request-linked user data and derived profile/analysis fields on every interaction, creating a built-in retention mechanism that extends beyond immediate response needs. In context, this is more dangerous because the skill already encourages storing natal profile data, so logs can become a second, less governed copy of sensitive user-linked information.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The mandatory logging section requires recording user identifiers, timezone, memory/profile hit state, and derived analysis fields for every request, but the skill never instructs the agent to warn users that this information is being logged or retained. This creates unnecessary user-linked observability data and can expose sensitive profiling information in logs beyond what is needed to answer the request.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The interface and default prompt are entirely in Chinese and do not provide any language-selection mechanism or indication that the skill can adapt to the user's preferred language. This can exclude or confuse users who do not read Chinese, and in multilingual environments it may cause misunderstanding of generated guidance, especially when the skill gives advice framed as recommendations or prohibitions.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
Line L74 instructs the skill to default to `Asia/Shanghai` whenever `user_timezone` is absent. This is a locale-specific policy choice expressed in natural language, and the file does not offer user choice or document a region-specific justification for imposing that timezone.

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
The file's instructional content is written entirely in Chinese and defines output requirements in Chinese without indicating that users may choose another language. Under the language/locale policy, forcing a specific language without opt-in can be a natural-language policy violation unless the constraint is explicitly justified as region-specific.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The cited passages assign family roles, value judgments, and fate interpretations based on gender in a rigid way, including derogatory framing for women. In a user-facing fortune or advisory skill, this can lead to discriminatory outputs, reputational harm, and potentially harmful guidance presented as personalized advice.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The entire file content is written exclusively in Chinese and provides no indication of alternative language support, user opt-in, or justification for a language-specific constraint. Under the stated policy, unqualified language forcing can be a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The file’s instructional content is entirely in Chinese, including operational guidance and warnings, with no indication that users may choose another language or that the skill is restricted to a Chinese-only audience. Under the policy, a fixed language/locale without opt-in or justification is a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
80% confidence
Finding
The document states that `updated_at` must use UTC with a `Z` suffix and explicitly forbids local timezone offsets. This is a natural-language locale policy constraint, and the file does not present it as an opt-in choice or user-selectable locale behavior.

Static analysis

No suspicious patterns detected.