T09 · Insecure Skill Coding Practices
- Location
scripts/guardlib.py:808- Finding
Unredacted Commands Can Expose Inline Credentials in JSON Reports
- Content
View full analysis
Vulnerability Details
File Location:
scripts/guardlib.py:808, with output serialization atscripts/preflight.py:57
Vulnerability Type: Plaintext sensitive-data exposure
Risk Level: MediumVulnerable Code
scripts/guardlib.py:808:python return { "command": command, "cwd": os.path.abspath(cwd), "allowed_roots": [os.path.abspath(root) for root in (allowed_roots or [cwd])], "risk": risk, "need_approval": need_approval, "primary_command": classification["primary_command"], "subcommand": classification["subcommand"], "categories": categories, "reasons": reasons, "compound_parts": display_parts, "path_findings": paths["findings"], "secret_findings": secrets["findings"], "context_findings": context["details"], "rollback": rollback, "safer_actions": safer["actions"], "safer_commands": safer["commands"], }scripts/preflight.py:53-57:python if args.format == "text": print(format_text(report)) else: print(json.dumps(report, indent=2))Technical Analysis
The secret-detection implementation masks recognized credentials in
secret_findings, butpreflight_report()also places the original, unmodified command in the report under thecommandfield. JSON is the default output format, andpreflight.pyserializes the entire report to standard output.Consequently, a command containing a bearer token, API key, cookie, password, JWT, or another credential can produce a report that contains both a masked finding and the original plaintext credential. Raw command segments may also remain in
compound_parts, while generated safer commands can retain command content.This conflicts with the Skill's purpose of detecting and reducing secret exposure. The implementation does not transmit reports over a network, but callers may capture standard output in Agent context, CI logs, shell trans ...[truncated 1147 chars]
- Remediation
View remediation
Remediation Suggestions
- Redact recognized secrets before placing commands into any report field.
- Apply redaction consistently to:
commandcompound_parts[*].command- nested command representations
safer_commands- reasons or diagnostics that might incorporate command fragments
- Preserve the original command only in process memory for analysis and never include it in serialized output after a secret is detected.
- Consider omitting the command field entirely when
secret_findingsis non-empty. - Add a centralized redaction function that replaces every matched secret span rather than independently rebuilding report fields.
- Add regression tests asserting that sentinel credentials do not occur anywhere in serialized JSON or text output.
- Document that command-line arguments may themselves be visible in process listings or shell history, and recommend the existing
--command-fileor standard-input modes for sensitive commands.
