T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/quick_validate.py:143
- Finding
- Detected Plaintext API Credentials Do Not Block Skill Packaging<![CDATA[ ## Vulnerability Details **File Location**: `scripts/quick_validate.py:143-158, 190-193`; packaging flow in `scripts/package_skill.py:52-63` **Vulnerability Type**: Plaintext credential exposure caused by non-fatal secret validation **Risk Level**: Medium ### Vulnerable Code ```python # scripts/quick_validate.py:143-158 key_patterns = [ (r'sk-[a-zA-Z0-9]{20,}', "OpenAI-style API key"), (r'AIzaSy[a-zA-Z0-9_-]{33}', "Google API key"), (r'sk-ant-[a-zA-Z0-9]{20,}', "Anthropic API key"), (r'sk_[a-f0-9]{40,}', "ElevenLabs-style API key"), ] for pattern, label in key_patterns: if re.search(pattern, body): warnings.append(f"Possible hardcoded {label} detected in SKILL.md body") ``` ```python # scripts/quick_validate.py:190-193 if warnings: warning_text = "; ".join(warnings) return True, f"Skill is valid! Warnings: {warning_text}" ``` ```python # scripts/package_skill.py:52-63 print("Validating skill...") valid, message = validate_skill(skill_path) if not valid: print(f"[ERROR] Validation failed: {message}") print(" Please fix the validation errors before packaging.") return None print(f"[OK] {message}\n") ``` ### Technical Analysis The validator recognizes several common plaintext API-key formats in the `SKILL.md` body. However, detection only appends a warning, and the validation function subsequently returns `True`. The packaging function interprets this result as successful validation and continues creating the distributable `.skill` archive. Consequently, a credential matching one of the detected patterns can be knowingly packaged even though the project's documented credential policy prohibits storing plaintext keys in Skill files. The current scan is also limited to the `SKILL.md` body; other regular files included by the packager are not examined for secrets. This is a fail-open security control: the system identifies a potentially sensitive value but does not enforce the policy required to prev ...[truncated 1504 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat detected credential patterns as fatal validation errors rather than warnings: ```python detected_secrets = [] for pattern, label in key_patterns: if re.search(pattern, body): detected_secrets.append(label) if detected_secrets: return False, ( "Possible plaintext credentials detected: " + ", ".join(detected_secrets) ) ``` 2. Scan every regular file selected for packaging, not only `SKILL.md`. Apply text scanning where appropriate and explicitly handle binary files, file-size limits, and decoding failures. 3. Extend detection to additional provider formats and generic high-entropy assignments such as `API_KEY=...`, while avoiding printing secret values in diagnostic output. 4. Add an allowlist for known non-sensitive placeholders and test fixtures rather than allowing all findings to pass. 5. If false-positive overrides are necessary, require an explicit, auditable command-line option. Packaging should fail securely by default. 6. Add regression tests that verify: - A detected credential in `SKILL.md` causes validation and packaging to fail. - A credential in a script, configuration file, or reference document also blocks packaging. - Validation messages never reproduce the detected secret. - Placeholder values do not cause unintended failures when explicitly recognized as safe. 7. Before distribution, use an established secret scanner as an additional defense-in-depth check and revoke any credential that may already have been packaged. ]]>
