T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:45- Finding
API Key Persisted in Plaintext in an Uncontrolled Working-Directory File
- Content
View full analysis
Vulnerability Details
File Location:
scripts/config.py:45-78; mandated bySKILL.md:17-18, 34
Vulnerability Type: Plaintext credential storage and unsafe configuration-file handling
Risk Level: MediumVulnerable Code
python def save_api_key_to_env(api_key: str) -> bool: """Save the API key to the .env file.""" try: env_path = Path(".env") lines = [] if env_path.exists(): lines = env_path.read_text(encoding="utf-8").splitlines() found = False new_lines = [] for line in lines: if line.startswith("XBY_APIKEY="): new_lines.append(f"XBY_APIKEY={api_key}") found = True else: new_lines.append(line) if not found: new_lines.append(f"XBY_APIKEY={api_key}") env_path.write_text("\n".join(new_lines) + "\n", encoding="utf-8") os.environ["XBY_APIKEY"] = api_key return True except Exception as e: print(f"Failed to save API key: {e}") return False def set_api_key(api_key: str) -> bool: """Set the API key and persist it to .env.""" if not api_key or not api_key.strip(): return False api_key = api_key.strip() if not save_api_key_to_env(api_key): return False settings.api_key = api_key return TrueThe corresponding Skill instructions require this behavior:
markdown - On first use, if `.env` does not contain `XBY_APIKEY`, the user must be asked for the API key. - After receiving the key, call `scripts.config.set_api_key(api_key)` to save it.Technical Analysis
The Skill persistently writes a user-provided API credential in plaintext to
Path(".env"), which resolves relative to the process's current working directory rather than a dedicated Skill configuration directory.The implementation does not:
- Apply restrictive permissions such as mode
0600. - Check whether
.envis a symbolic link. ...[truncated 1898 chars]
- Apply restrictive permissions such as mode
- Remediation
View remediation
Remediation Suggestions
- Do not persist credentials by default. Prefer a session-only environment variable or an operating-system credential manager.
- If persistence is explicitly requested by the user, use a dedicated per-user configuration directory rather than the current working directory.
- Create the credential file with restrictive permissions such as
0600, and verify those permissions whenever it is loaded. - Reject symbolic links and non-regular files before reading or writing the credential file.
- Update the file atomically using a securely created temporary file in the same directory, then replace the destination.
- Warn users never to commit the credential file and provide an appropriate
.gitignoreentry. - Avoid placing the key in the process environment unless required, because child processes may inherit it.
- Provide key revocation and rotation guidance in the Skill documentation.
