Back to skill

Security audit

灵犀六爻

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it advertises, but it keeps local history and can send a reading to OpenAI only when that option is enabled.

Install only if you are comfortable with consultations being saved locally in plaintext. Avoid entering highly sensitive personal, medical, legal, financial, or relationship details unless you manage or delete the history file, and use --llm only when you are willing to send the question and reading context to OpenAI.

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/liuyao.py:345
Finding

Automatic Plaintext Retention of Sensitive Consultation Data

Content
View full analysis

Vulnerability Details

File Location: scripts/liuyao.py, lines 345-348 and 416-445
Vulnerability Type: Automatic plaintext storage of potentially sensitive user data
Risk Level: Medium

Vulnerable Code

python
def save_history(history_path: Path, payload: Dict[str, object]) -> None:
    history_path.parent.mkdir(parents=True, exist_ok=True)
    with history_path.open("a", encoding="utf-8") as f:
        f.write(json.dumps(payload, ensure_ascii=False) + "\n")

The function is invoked unconditionally with the raw question and generated consultation details:

python
save_history(
    Path(args.history),
    {
        "ts": now.isoformat(),
        "question": args.question,
        "ben_gua": {"name": ben.name, "code": ben.code},
        "bian_gua": {"name": bian.name, "code": bian.code},
        "day_ganzhi": day_gz,
        "month_jian": month_branch,
        "kongwang": f"{kongwang[0]}{kongwang[1]}",
        "yongshen": yongshen,
        "judgment": judgment,
        "score": score,
        "advice": advice,
        "judge_trace": judge_meta.get("trace", []),
        "lines": [
            {
                "line": ln.index,
                "value": ln.ben.value,
                "moving": ln.ben.is_moving,
                "yin_yang": "阳" if ln.ben.is_yang else "阴",
                "bian_yin_yang": "阳" if ln.bian_is_yang else "阴",
                "branch": ln.branch,
                "element": ln.element,
                "liuqin": ln.liuqin,
                "liushen": ln.liushen,
                "shi": ln.is_shi,
                "ying": ln.is_ying,
            }
            for ln in pan_lines
        ],
    },
)

Technical Analysis

Every execution unconditionally appends the user's raw question and the complete generated result to a JSONL file. Consultation questions can contain sensitive information concerning health, employment ...[truncated 2236 chars]

Remediation
View remediation

Remediation Suggestions

  1. Make history retention opt-in rather than unconditional, such as through an explicit --save-history option.
  2. Provide a clear --no-history mode and document the default retention behavior before accepting user data.
  3. Avoid storing the raw question unless it is essential. Offer redaction, pseudonymization, or storage of only non-sensitive result metadata.
  4. Create new history files with owner-only permissions, such as mode 0600, and verify existing files are not group- or world-readable.
  5. Validate the selected history destination and warn when it is inside a shared, synchronized, temporary, or publicly accessible directory.
  6. Implement configurable retention limits, record deletion, and history-clearing functionality.
  7. If durable sensitive storage is required, use encryption at rest with keys managed separately from the history file.
  8. Inform users exactly which fields are retained, where the file is located, and how to disable or delete the stored history.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (9)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes a local Python script, reads environment variables for an API key, and writes history to disk, but the manifest declares no explicit tool scope or permission boundaries. This creates an authorization ambiguity where the runtime may grant broader access than users or reviewers expect, increasing the risk of unintended file access, secret exposure, or persistent data storage.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The trigger description matches broad conversational terms such as '占卜解读' and related divination vocabulary that can easily appear in normal discussion, causing the skill to activate unexpectedly. Misfires matter here because the skill can read environment variables, write history, and invoke a script, so accidental activation may expose data handling behaviors users did not intend.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description suggests a local divination/history tool, but the code can optionally transmit the user's question, the generated judgment, and gua details to OpenAI when --llm is enabled. This creates an undocumented external data flow that users may not expect, especially because divination questions can contain sensitive personal, financial, health, or legal information.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The full question text and divination output are sent to an external LLM API, but the code provides no user-facing warning, consent prompt, or disclosure of third-party processing. Because users may ask about relationships, health, money, or disputes, this can leak highly sensitive natural-language content outside the local environment.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code reads OPENAI_API_KEY from the environment and invokes a remote chat completion API even though the core skill purpose is local divination and advice generation. While not credential exfiltration itself, this expands trust boundaries and enables third-party disclosure of user content without being obviously necessary for the stated function.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The LLM prompt forwards the user's full question along with derived divination results to an external model provider. In this skill context, questions are especially likely to contain sensitive personal data, so sending the full text to a third party increases privacy risk beyond what users would reasonably infer from a local divination tool.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill persistently stores sensitive question history and generated outputs in a local JSONL file without an explicit warning, retention policy, or opt-in. Plain-language records of users' personal concerns can be exposed to other local users, backups, logs, or later tooling that reads the file.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code logs the user's question, judgment, advice, and detailed line analysis to persistent local storage in plain language without minimization or opt-in. Since divination queries naturally invite disclosure of intimate personal matters, this creates a meaningful privacy and data leakage risk in the skill's context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-facing strings, prompt instructions, CLI descriptions, and result output are all fixed in Chinese, and the LLM prompt explicitly instructs responses in that language context. This can violate a language/locale policy when no user opt-in or documented regional justification is provided.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.