Back to skill

Security audit

doc-desens-scanner

Security checks for vulnerabilities and agentic risk

Overview

This desensitization skill has a coherent purpose, but its audit report can re-expose sensitive values it claims to redact and its declared permissions do not match its file-reading CLI behavior.

Review before installing. Use the scanner only on files you intentionally select, and do not share --report output externally unless it has been fixed to remove raw samples. The publisher should align the declared permissions with the CLI behavior and change reports to include only non-sensitive metadata such as type, offset, and length.

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/desens_scan.py:56
Finding

Audit Report Re-Exposes Sensitive Values from Scanned Content

Content
View full analysis

Vulnerability Details

File Location: scripts/desens_scan.py, lines 56–59
Vulnerability Type: Sensitive information disclosure through report output
Risk Level: Medium

Vulnerable Code

python
if a.report:
    rep = [{"type": n, "sample": f[:12] + ("…" if len(f) > 12 else "")} for n, _, f in hits]
    print("\n--- desens_report ---")
    print(json.dumps({"count": len(hits), "items": rep}, ensure_ascii=False, indent=2))

Technical Analysis

When --report is enabled, the scanner copies the first 12 characters of every detected sensitive value into the report printed to standard output. This occurs after the main document has been masked, causing the secondary audit artifact to retain source data that the Skill is specifically intended to remove.

The disclosure is not limited to harmless metadata. The detection rules accept secrets as short as eight characters after prefixes such as sk- or ghp_. Consequently, a matched value may be no longer than 11 or 12 characters and can therefore be included in the report in full. Other recognized values, such as an 11-digit phone number, can likewise be reproduced completely.

The relevant input comes from the user-selected document, code, log, file, or --text value. The dangerous operation is the insertion of raw match substrings into an audit record. The crossed trust boundary is between confidential source material and the externally deliverable desensitization result: SKILL.md lines 70–74 describe producing the redacted content, a full risk list, and an attached audit log when delivering the result.

This is a reachable coding vulnerability rather than evidence of intentional credential theft or malicious behavior.

Attack Path

  1. A document, code file, or log contains a credential, phone number, internal path, codename, or other value matched by the scanner.
  2. The user or Agent invokes scripts/desens_scan.py with --report, consistent ...[truncated 1472 chars]
Remediation
View remediation

Remediation Suggestions

Remove all raw match substrings from report output. Reports should contain only non-sensitive metadata, such as:

  • Finding type
  • Number of findings
  • Character offsets or line numbers
  • A non-reversible, keyed fingerprint when correlation is necessary

Do not use fixed-length prefixes as masking because short values can be exposed completely and longer credential prefixes may still be sensitive.

A safer report construction would be:

python
rep = [
    {
        "type": name,
        "offset": position,
        "length": len(fragment),
    }
    for name, position, fragment in hits
]

Additional hardening should include:

  1. Keep audit reports out of externally shared output by default.
  2. Clearly distinguish local diagnostic reports from sanitized deliverables.
  3. Add tests asserting that no original phone number, token, password, internal path, or codename appears in report output.
  4. If previews are operationally required, use type-aware irreversible placeholders rather than any original substring.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (10)

Scope Creep

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

The risk rationale states the skill may call APIs and perform local execution, while the manifest declares both network and subprocess access disabled. Contradictory capability declarations undermine trust in the skill's security boundaries and can lead to incorrect sandboxing or approval decisions for a tool handling sensitive content.

Content

No source excerpt is available for this finding.

Scope Creep

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest says filesystem access is disabled, yet the documented usage requires reading target files from disk via a file path argument. This mismatch can break policy enforcement, confuse reviewers, or cause the platform to grant/deny capabilities incorrectly, which is especially dangerous for a tool that processes potentially sensitive local documents.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill advertises activation on very broad natural-language phrases such as 'scan before external release', 'privacy redaction', and related variants, which can overlap with ordinary document-handling requests. In an agentic environment, this increases the chance of unintended skill invocation on unrelated content, causing over-collection, unnecessary scanning of sensitive documents, or redaction actions the user did not explicitly request.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The description lists trigger terms such as “去敏”, “脱敏”, and “PII” alongside general situations like “收到『先脱敏』类指令”, but it does not define boundaries or negative examples for when the skill should not activate. These terms can occur in ordinary conversation or unrelated contexts, making invocation scope ambiguous for a manifest file.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The read_when section uses general conditions like external sharing, leakage concerns, privacy self-checks, and “先脱敏” instructions, but does not specify constraints such as required file inputs, supported content types, or situations to ignore. For a manifest file, this leaves activation ambiguous and increases the chance of unintended invocation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation promises automatic masking/redaction and audit-log generation, but this file provides only descriptive metadata and no evidence that those controls exist or are enforced. In a security/privacy skill, overstating protections can cause users or orchestrators to rely on nonexistent safeguards and release sensitive data under a false sense of safety.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger description uses very broad, everyday natural-language examples such as 'scan before sending out' and 'don't expose internal paths/keys/names', which can match many ordinary user requests beyond a narrowly scoped desensitization workflow. In an agent ecosystem, this can cause over-triggering or invocation in ambiguous contexts, leading the skill to process unintended content or override more appropriate skills.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file presents the skill instructions entirely in Chinese and labels the document as an AI skill manual without indicating that language is optional or user-selectable. Under the policy, a fixed language requirement without opt-in can be a locale/language policy concern unless justified or the user is offered a choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The License & attribution section is presented primarily in Chinese and includes mandatory-looking instructions such as "务必并读" and a required copied block, but it does not offer an equivalent fully English version or indicate user choice of language. This can be read as imposing a specific language/locale for important usage conditions without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The natural-language content of the file is entirely in Chinese and does not indicate that other languages are supported or that the user can opt into a preferred language. Under the stated policy, a language constraint should be optional or explicitly justified.

Content

No source excerpt is available for this finding.