Back to skill

Security audit

Npc Distill Main

Security checks for vulnerabilities and agentic risk

Overview

The skill is purpose-coherent and not clearly malicious, but it handles sensitive workplace/person data and has risky URL fetching, command execution, dependency, and retention practices that need review before installation.

Install only if you are comfortable storing sensitive interpersonal/workplace material as local plaintext files. Use a dedicated private directory, avoid shared drives and repositories, review every diff before writes, do not fetch internal/private URLs through the skill, and treat delete_corpus as archive/comment-out rather than deletion. Pin and install dependencies in an isolated environment, and avoid executing template commands through a shell with untrusted aliases or IDs.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
templates/ingest-url.md:28
Finding

Shell Command Injection Through User-Controlled Alias Interpolation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
templates/ingest-url.md:16
Finding

Unrestricted User-Supplied URL Fetching Enables SSRF

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Unpinned Dependency Is Eligible for Automatic Installation

Content
View full analysis
=6.0 ``` The compatibility guidance additionally recommends installation without version or integrity verification: ```bash pip install pyyaml ``` It states that some hosts may automatically run `pip install` when the dependency is unavailable. ### Technical Analysis The lower-bound-only constraint allows any future PyYAML release to satisfy the dependency. No lockfile, package hash, trusted index restriction, or reviewed upper bound is supplied. Python package installation can execute package build and installation logic. If the upstream package, distribution channel, dependency resolution process, or a future release is compromised, automatic installation would execute that code with the privileges of the Agent's Python environment. The package name is not currently shown to be typosquatted, and the audited code uses `yaml.safe_load`; the confirmed weakness is the absence of reproducible and integrity-verified dependency resolution combined with guidance allowing automatic installation. ### Attack Path 1. The Skill runs in an environment where PyYAML is absent. 2. Compatibility guidance causes the host to install the dependency automatically or prompts the user to run the documented command. 3. Package resolution selects the newest release accepted by `pyyaml>=6.0`. 4. A compromised, malicious, or unexpectedly incompatible release is downloaded. 5. Package installation logic executes in the local Python environment. 6. Malicious package code gains the permissions of the installing user or Agent process. ### Impact Assessment If the dependency supply chain is compromised, impact could include: - Arbitrary code execution during install ...[truncated 415 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/update_memory.py:227
Finding

Deletion Retains Sensitive Records in Comments and Backup Files

Content
View full analysis
list[str]: """Comment out one corpus record instead of deleting it.""" for entry in memory.corpus_entries: if entry.corpus_id == corpus_id: # Wrap raw_body in an HTML comment. entry.raw_body = f"" return [f"Commented corpus: {corpus_id}"] return [f"Corpus not found: {corpus_id}"] ``` Every save also creates a predictable plaintext backup containing the previous file contents: ```python # Backup if target.exists(): backup = target.with_suffix(target.suffix + ".bak") shutil.copy2(target, backup) ``` ### Technical Analysis The operation presented as deletion only changes Markdown rendering. The original record remains intact and can be recovered by opening the source file. The next save also copies the prior complete memory file to a `.bak` file. These files may contain conversations, workplace material, behavioral inferences, rehearsal transcripts, and other information about real people. Using an alias instead of a name reduces direct identification but does not anonymize contextual content. The documented retention model therefore fails to provide actual deletion. It also creates additional copies without an expiration policy or explicit permission controls. ### Attack Path 1. A user stores sensitive source material or behavioral observations in a memory file. 2. The user requests deletion of a corpus entry. 3. The function wraps the original entry in an HTML comment instead of removing it. 4. Saving the file creates o ...[truncated 942 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (22)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This skill is specifically designed to ingest emails, chats, meeting notes, annotations, and URL-sourced communications about identifiable individuals, then store distilled profiles locally. Without a prominent upfront warning and consent/privacy guidance, users may unintentionally process confidential or personal data, creating substantial privacy, compliance, and insider-surveillance risks.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documented activation triggers are very broad and include common natural-language phrases, which can cause the skill to auto-activate on unrelated user requests. In this skill’s context, unintended activation is more dangerous because it handles sensitive interpersonal data and may prompt collection, storage, or transformation of private communications without a clear, deliberate opt-in boundary.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documents file read/write behavior and instructs the agent to modify local memory files, but it does not declare any explicit tool scope or permission boundaries. In agents that auto-wire tools based on skill content, this can enable unintended filesystem access or broader writes than the user expects, especially because the skill is triggered by common collaboration scenarios.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are broad enough to match ordinary requests like drafting, rehearsal, or discussing a person's preferences, which can cause the skill to activate unexpectedly. In this skill, unexpected activation is more dangerous because it may start ingesting, summarizing, and persisting sensitive interpersonal communications to local storage without sufficiently clear user intent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown skill presents all operative guidance, examples, and instructions in Chinese only, with no indication that the user can choose another language or that the locale restriction is intentional and justified. That can violate a language/locale policy when users are not given an opt-in or alternative.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The document states that some hosts may automatically run pip install pyyaml on first use, but it does not warn users about the risks of installing packages at runtime on the host system. Automatic dependency installation can modify the local environment, pull code from external package indexes, and create supply-chain exposure or unexpected execution on machines where the skill is supposed to remain local and privacy-preserving.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The entire specification mandates a Chinese-language memory format and field semantics, such as Chinese section names and examples, with no indication that users can opt into another language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This markdown file contains operational guidance to rewrite the entire memory file and create backup copies before modification. Those actions affect user data on disk, but the document does not include any warning or disclosure about file modification, backup artifact creation, or the need to obtain user awareness before proceeding.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code file contains user-facing natural-language content such as the module docstring and argument help text that assumes Chinese as the only language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script creates and updates a persistent local memory file without any explicit user-facing disclosure or confirmation at the point of write. In this skill’s context, the stored data consists of sensitive interpersonal communications and inferred profiles, so silent persistence can violate user expectations and increase privacy and compliance risk even if storage is only local.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script ingests arbitrary signals JSON and persists its contents into long-lived memory without disclosing that supplied text, URLs, and extracted traits will be stored. Because this skill is specifically designed to accumulate speech, emails, chats, and behavioral inferences about named individuals, the lack of disclosure is more dangerous than usual and can lead to covert retention of highly sensitive personal or corporate data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire skill is written as mandatory Chinese prompts and response templates, including fixed user-facing confirmations and follow-up suggestions. There is no indication that the user may choose another language or that the locale restriction is optional or justified as region-specific, which is a natural-language policy violation 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

The file’s operational prompts and instructions are exclusively in Chinese, which can force a specific language on users or operators without any stated opt-in. The policy only permits this when a language choice is offered or the locale restriction is clearly justified, neither of which appears here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The entire skill instruction set, trigger text, and user-facing scripted responses are written only in Chinese, and the workflow directs the assistant to use those responses during operation. There is no indication that the user can choose another language or that the Chinese-only constraint is justified as a region-specific requirement, which makes this a natural-language policy violation 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
96% confidence
Finding

The entire skill is written as mandatory Chinese workflow and output templates, including fixed Chinese prompts and report structure, with no indication that the user may choose another language. This creates a natural-language policy concern because it imposes a specific language/locale without opt-in or documented justification.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow explicitly tells the agent to search a shared memory.md corpus for relevant historical material after loading a per-person profile, which conflicts with the stated privacy model of keeping data isolated in memory-{npc_id}.md. In a skill built around sensitive communications and executive/persona modeling, this can cause cross-person data mixing and unauthorized disclosure of another subject's messages, notes, or behavioral profile.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The '反例' section says '不要替用户回答提问', framing the exercise as practice rather than doing the work for the user. However, step 7 option 2 tells the agent to '帮你把雷区都改掉,润色到符合他风格', which actively performs the substantive revision instead of keeping the interaction purely as rehearsal.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The README consistently presents the skill interface, examples, and expected usage in Chinese, and the contribution section notes templates are mainly Chinese. There is no explicit statement that users may choose their preferred language at runtime, which can be a locale/language policy concern when the skill is used in broader multilingual environments.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest description says '所有数据存储在本地单一memory文件中', which implies one single memory file. However, the Quick Reference later documents storage as '~/npc-distill/memory-{npc_id}.md', indicating one file per NPC rather than a single file overall. This is a semantic mismatch between the claimed storage model and the actual documented behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The Quick Reference states '永远不要写真名', suggesting strict avoidance of real names in stored representations. Elsewhere, the usage documentation repeatedly frames the workflow around analyzing 'X 说的/写的' and specific people's content, which does not itself guarantee contradiction, but the stronger contradiction is that the storage guidance claims strict pseudonymization while no documented enforcement mechanism is described. The documentation therefore overstates the guarantee compared with what the skill actually specifies.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency is specified as pyyaml>=6.0 without an upper bound or exact pin, which makes builds non-reproducible and allows different environments to install different releases over time. In a skill that may process user-supplied content and URLs, dependency drift increases supply-chain risk and makes it harder to verify that a safe version is consistently deployed.

Content

Scanner excerpt · scripts/requirements.txt (reported line 1)May include surrounding context.

text
pyyaml>=6.0

Unverifiable Dependency: pyyaml has 8 known advisory(ies) (CVE-2019-20477 (Deserialization of Untrusted Data in PyYAML); CVE-2020-1747 (Improper Input Validation in PyYAML); CVE-2020-14343 (Improper Input Validation in PyYAML) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

PyYAML has a history of deserialization and input-validation advisories, and because the requirement is not pinned, it is impossible to determine from this manifest alone whether deployments will receive an affected version. Given this skill's purpose of ingesting pasted text, meeting notes, chats, and URL-derived content, any unsafe YAML handling elsewhere in the project would be more concerning because inputs may be attacker-controlled or sensitive.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.