T09 · Insecure Skill Coding Practices
- Location
SKILL.md:22- Finding
Plaintext API Key Storage in the Project Directory
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:22-24;scripts/search.py:25, 28-40, 144-149
Vulnerability Type: Plaintext sensitive credential storage
Risk Level: MediumVulnerable Code and Instructions
SKILL.md:22-24instructs the Agent to use a file inside the project for credential storage:markdown - 检查`references/api_key.md`文件是否存在 - 如果存在,读取其中的api_key - 如果文件不存在,提示用户输入API密钥,并将用户输入的密钥保存到`references/api_key.md`文件中In English, these instructions require checking
references/api_key.md, reading its API key when present, and saving a user-provided API key there when absent.scripts/search.py:25, 28-40reads that plaintext credential:python API_KEY_FILE = SKILL_DIR / "references" / "api_key.md" def load_api_key() -> str | None: """ Load API key from file. Returns the API key if found and valid, None otherwise. """ try: if API_KEY_FILE.exists(): content = API_KEY_FILE.read_text(encoding="utf-8").strip() lines = content.splitlines() if len(lines) >= 1 and lines[0] and not lines[0].startswith("YOUR_API_KEY"): return lines[0].strip() except Exception: # File read error, return None pass return Nonescripts/search.py:144-149makes that project-local file the required credential source:python # Load API key from file api_key = load_api_key() if not api_key: print("Error: API key is required. Please save it in references/api_key.md", file=sys.stderr) sys.exit(1)Technical Analysis
The documented setup workflow directs an Agent to persist a reusable API credential in plaintext under the Skill's source tree. The loader reads the first line of that file without validating or enforcing restrictive file permissions. The audited project contains no
.gitignorerule protecting this path and no credential-store integration.The bundled
references/api_key.mdwas empty during the a ...[truncated 2258 chars]- Remediation
View remediation
Remediation Suggestions
- Remove the instruction to save credentials under
references/api_key.md. - Read the token from an environment variable, such as
MYSTEEL_API_KEY, or use an operating-system credential manager. - If file-based storage is unavoidable:
- Store the credential outside the project and source-control tree.
- Create the file with owner-only permissions, such as mode
0600on POSIX systems. - Reject files whose ownership or permissions allow access by other users.
- Add the credential path to
.gitignoreand relevant packaging exclusions. - Include only a non-secret example file, never a populated credential file.
- Avoid silently suppressing credential-file read errors. Report permission and format failures without printing the secret.
- Document token rotation and revocation procedures in case the project has already been shared or committed.
- Clearly disclose that both the token and user query are sent to the documented Mysteel service.
- Remove the instruction to save credentials under
