T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:45- Finding
API Credential Persisted in an Unprotected Plaintext Environment File
- Content
View full analysis
Vulnerability Details
File Location:
scripts/config.py:45-63
Vulnerability Type: Plaintext sensitive-data storage with insufficient file-permission enforcement
Risk Level: MediumThe persistence behavior is explicitly required by
SKILL.md:17-18andSKILL.md:34.Vulnerable Code
python def save_api_key_to_env(api_key: str) -> bool: """Persist 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 FalseTechnical Analysis
The function permanently writes the user-provided
XBY_APIKEYinto a plaintext.envfile in the process's current working directory.Path.write_text()does not explicitly enforce owner-only permissions. A newly created file therefore receives permissions derived from the process umask, while an existing file retains its existing permissions. In environments with a permissive umask or a previously over-permissive.env, other local users or processes may be able to read the credential.The implementation also accepts internal carriage-return or newline characters. Although
set_api_key()strips leading and trailing whitespace, embedded line breaks remain valid and are interpolated directly into the file. A crafted value can consequently injec ...[truncated 2261 chars]- Remediation
View remediation
Remediation Suggestions
- Prefer an operating-system credential store, deployment secret manager, or session-scoped environment variable instead of persistent plaintext storage.
- Obtain explicit user consent before persisting the key and clearly document where it will be stored and how it can be revoked.
- Reject values containing
\r,\n, or NUL characters before writing:python if any(char in api_key for char in ("\r", "\n", "\0")): return False - Create and maintain the
.envfile with owner-only permissions (0600). Verify and correct permissions even when the file already exists. - Write updates atomically through an owner-only temporary file, then replace the destination to reduce corruption and race risks.
- Avoid storing unrelated settings in the same credential file. If persistence is unavoidable, use a dedicated file outside shared project directories.
- Ensure
.envis excluded from source control, archives, diagnostic bundles, and automated logs. - Provide credential rotation and revocation instructions in
SKILL.md, and recommend immediate rotation if the file may have been exposed.
