T09 · Insecure Skill Coding Practices
- 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: MediumVulnerable 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
--reportis 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-orghp_. 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
--textvalue. 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.mdlines 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
- A document, code file, or log contains a credential, phone number, internal path, codename, or other value matched by the scanner.
- The user or Agent invokes
scripts/desens_scan.pywith--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:
- Keep audit reports out of externally shared output by default.
- Clearly distinguish local diagnostic reports from sanitized deliverables.
- Add tests asserting that no original phone number, token, password, internal path, or codename appears in report output.
- If previews are operationally required, use type-aware irreversible placeholders rather than any original substring.
