Back to skill

Security audit

Lao Huangli

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent Chinese almanac calculator, with a supply-chain and network-cache caveat users should understand before running it.

Install and run this skill only in an environment where Python package downloads and a possible Skyfield/JPL ephemeris download are acceptable. For stricter environments, preinstall dependencies from trusted sources, pin hashes or use a lockfile, pre-provision and verify de440s.bsp, and treat the almanac output as cultural reference rather than legal, medical, financial, or safety advice.

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

T08 · Insecure Dependencies

Warning
Location
src/lao_huangli/astronomy.py:49
Finding
Unverified Third-Party Dependencies and Automatically Retrieved Ephemeris Artifact## Vulnerability Details **File Location**: `src/lao_huangli/astronomy.py:49-67`; related dependency declarations and installation instructions appear in `requirements.txt:1-2`, `SKILL.md:124-127`, and `scripts/huangli_calc.py:795-803`. **Vulnerability Type**: Supply-chain integrity failure caused by dependencies and runtime artifacts retrieved without cryptographic verification. **Risk Level**: Medium ### Vulnerable Code ```python def _cache_dir() -> Path: path = Path.home() / ".cache" / "lao-huangli" / "skyfield" path.mkdir(parents=True, exist_ok=True) return path @lru_cache(maxsize=1) def _loader() -> Loader: return Loader(str(_cache_dir())) @lru_cache(maxsize=1) def _timescale(): return _loader().timescale() @lru_cache(maxsize=1) def _ephemeris(): return _loader()(EPHEMERIS_NAME) ``` The requested ephemeris filename is defined without an accompanying expected digest: ```python DEFAULT_TIMEZONE = "Asia/Shanghai" EPHEMERIS_NAME = "de440s.bsp" ``` The dependencies are version-pinned but not hash-pinned: ```text skyfield==1.54 jplephem==2.24 ``` The documented installation path retrieves these packages from the configured Python package index: ```bash uv venv .venv uv pip install --python .venv/bin/python -r skills/lao-huangli/requirements.txt ``` The CLI also recommends an on-demand dependency installation command: ```python print( "缺少老黄历运行依赖:" f"{IMPORT_ERROR.name}\n" "推荐直接用 uv 运行,无需本地安装:\n" f" uv run --with skyfield==1.54 --with jplephem==2.24 python {script_path} 2026 3 9 12 --profile market-folk-v1 --format markdown\n" "或先安装依赖:\n" " uv venv .venv\n" " uv pip install --python .venv/bin/python -r skills/lao-huangli/requirements.txt", file=sys.stderr, ) ``` ### Technical Analysis Version pinning prevents unintended version upgrades but does not authenticate downloaded package contents. The project does not provide a lockfile containing cryptographic hashes or require hash verification ...[truncated 2784 chars]
Remediation
## Remediation Suggestions 1. Generate and commit a reproducible dependency lockfile containing SHA-256 hashes for every package and transitive dependency. 2. Enforce hash verification during installation, such as a hash-locked requirements workflow with `--require-hashes`. 3. Restrict package retrieval to explicitly configured HTTPS repositories and avoid untrusted package mirrors. 4. Pin the expected source URL and SHA-256 digest of `de440s.bsp`. 5. Verify the ephemeris digest before every load, including when an existing cached copy is reused. 6. Delete and reject cached artifacts that fail verification rather than silently downloading or processing them. 7. Prefer bundling a verified ephemeris when licensing and package-size constraints permit. 8. If runtime retrieval remains necessary, require explicit user approval and document the remote host, artifact size, expected digest, and cache location. 9. Consider using a project-controlled, permission-restricted cache rather than an implicitly shared user-level cache. 10. Run dependency installation and calendar calculation inside a least-privilege environment without access to unrelated credentials or sensitive files.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (26)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
start_branch = rule["monthStarts"][month_branch]
    start_index = DIZHI.index(start_branch)
    day_index = DIZHI.index(day_branch)
    return rule["order"][(day_index - start_index) % 12]


def compute_duty_god(profile_id: str, month_branch: str, day_branch: str) -> str:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
start_branch = rule["monthStarts"][month_branch]
    start_index = DIZHI.index(start_branch)
    day_index = DIZHI.index(day_branch)
    return rule["order"][(day_index - start_index) % 12]


def compute_duty_god(profile_id: str, month_branch: str, day_branch: str) -> str:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
start_branch = rule["monthStarts"][month_branch]
    start_index = DIZHI.index(start_branch)
    day_index = DIZHI.index(day_branch)
    return rule["order"][(day_index - start_index) % 12]


def compute_duty_god(profile_id: str, month_branch: str, day_branch: str) -> str:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Lp3

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

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This JSON file consists entirely of Chinese-language rule names, reasons, and values, and it provides no indication that the skill is region-specific or that users can opt into this locale. Under the stated policy, forcing a specific language without opt-in or documented justification is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This JSON file contains natural-language labels ("出行", "嫁娶") that force a specific language/locale. Under the policy, language constraints should either be optional for the user or clearly documented as region-specific, and neither is evident in this file.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
The JSON content is entirely encoded in Chinese text values, including work titles, reasons, and items, with no indication that users may choose another language or locale. Under the stated policy, hard-coding a single language without opt-in can constitute a natural-language policy violation when no justification or alternative is documented in the file.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This Python skill embeds Chinese-only labels and output strings throughout the file, including zodiac names, weekdays, rendered calendar text, and runtime error/help messages. Because the skill forces a specific language/locale in user-facing output without user opt-in or a documented region-specific policy justification, it matches the natural-language locale policy violation criteria.

Description-Behavior Mismatch

Medium
Confidence
82% confidence
Finding
Calling the Skyfield loader on an ephemeris filename can trigger network retrieval if the file is not already cached, creating undeclared outbound network access and importing unpinned third-party data at runtime. In a skill presented as a computational calendar helper, this hidden fetch behavior can violate sandbox expectations, fail in restricted environments, or expose usage metadata through external requests.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The ephemeris load path may silently download external data without any user-facing notice or consent, which is risky in privacy-sensitive or air-gapped deployments. Even if the downloaded file is legitimate, undisclosed outbound connectivity expands the trust boundary and can surprise operators who expect purely local computation.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
The document specifies a default timezone of `Asia/Shanghai`, which imposes a locale-specific setting in natural language content. While the subject matter is culturally Chinese, the file does not explicitly state that this skill is intended only for that regional/calendar context or offer user choice, so it may conflict with language/locale policy expectations.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
This markdown file is entirely written in Chinese and does not offer any language choice or indicate that the skill is intentionally limited to Chinese-speaking users. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is clearly documented and justified.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
This JSON file contains only Chinese-language names and notes in user-visible fields such as `work`, `order`, `goodGods`, `badGods`, and `notes`, but does not indicate that the skill is China-/Chinese-specific or that users can opt into this locale. Under the stated policy, hard-coding a single language without opt-in can be a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
79% confidence
Finding
This JSON file contains user-facing natural-language values exclusively in Chinese, including the cited work names and notes, with no indication that the skill is intentionally region-specific or that users can opt into this locale. Per the policy, forcing a specific language without opt-in can be a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The file consists entirely of Chinese-language rule labels and descriptions, and there is no accompanying natural-language indication that the skill is intentionally limited to Chinese users or a China-specific locale. Under the policy rule, forcing a specific language without opt-in can be a locale/language policy issue.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The natural-language note on L46 is written entirely in Chinese, which imposes a specific language presentation without offering user opt-in or an alternative locale. Under the policy for all file types, forced language or locale in natural-language content is a reportable issue unless clearly documented as region-specific or optional.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
This JSON file embeds only Chinese-language titles, labels, and domain values in user-visible fields such as work names, order entries, month mappings, and notes. Under the stated policy, forcing a specific language or locale without offering a choice can be a natural-language policy violation, and this file contains no indication that the locale constraint is optional or region-specific.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The JSON file defines user-facing labels only in Chinese ("财神", "喜神") and provides no indication that this skill is region-specific or that users can select another language. Under the policy for natural-language violations, forcing a specific language without opt-in is a reportable issue.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The JSON content includes user-facing natural language only in Chinese, such as the note on L21, with no indication that other languages are supported or that the locale is intentionally region-specific. Under the stated policy, fixed language use without opt-in can be a natural-language locale violation.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The config references a zh-hans URL at L09 and a zh-hant URL at L14, which embeds an implicit locale choice in user-visible source material. Because the file provides no note that users may choose locale or that mixed-script sources are intentional, this can be interpreted as a language/locale policy issue.

Natural-Language Policy Violations

Low
Confidence
80% confidence
Finding
This JSON file uses Chinese-language values and notes throughout, including the source work title and explanatory text. Under the stated policy, forcing a specific language without user choice or justification can be a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
80% confidence
Finding
This JSON file includes user-facing natural-language values such as the work title and notes entirely in Chinese, but provides no indication that the skill is Chinese-language or region-specific, nor any user opt-in for language/locale. Under the stated policy, forcing a specific language without documented choice or justification is a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
This JSON manifest contains natural-language and URL values that explicitly lock the source material to Chinese-language Wikisource pages, including `zh-hans` paths and Chinese-only metadata. Under the policy rule for language/locale constraints, this can be a concern when no user opt-in or justification is provided in the file.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
This JSON file encodes all referenced works, notes, and domain values entirely in Chinese, with no indication that users can choose another language or that the skill is explicitly limited to Chinese-speaking contexts. Under the policy rule for natural-language violations, a fixed language without opt-in can be a locale-policy issue.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The module hard-codes `DEFAULT_TIMEZONE = "Asia/Shanghai"`, causing date and solar-term calculations to default to a specific regional locale unless callers override it. This is a natural-language policy concern because the skill imposes a locale-specific behavior by default rather than explicitly obtaining user choice.

Static analysis

No suspicious patterns detected.