T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:39- Finding
API Credential Stored in an Unprotected Plaintext Environment File
- Content
View full analysis
Vulnerability Details
File Location:
scripts/config.py, lines 39-61
Vulnerability Type: Plaintext credential storage and environment-file injection
Risk Level: MediumVulnerable Code:
python def save_api_key_to_env(api_key: str) -> bool: """将API key保存到.env文件""" 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"保存API key失败: {e}") return FalseTechnical Analysis
A user-supplied API credential is persisted in a predictable
.envfile as plaintext. The file is created usingPath.write_text()without explicitly enforcing restrictive permissions. Consequently, its confidentiality depends on the process umask and the permissions of the containing directory.The API key is also interpolated directly into an environment-file assignment without rejecting carriage returns or newline characters. A crafted key containing line breaks can introduce additional entries into
.env. Those entries may subsequently be interpreted by this project or another dotenv-compatible process.The Skill documentation explicitly directs the agent to collect and persist the credential, so this exposure occurs during the intended workflow rather than only through an exceptional code path.
Attack Path
Credential disclosure path:
- A user suppli ...[truncated 1521 chars]
- Remediation
View remediation
Remediation Suggestions
- Prefer an operating-system credential store, secrets manager, or ephemeral environment variable instead of writing the key to the project directory.
- Obtain explicit user consent before persisting any credential and provide an option to keep it only in memory.
- If file persistence is unavoidable, create the secrets file atomically with owner-only permissions such as
0600; do not rely solely on the current umask. - Reject API-key values containing carriage returns, newlines, NUL bytes, or other control characters before storage.
- Ensure
.envis excluded from source control, build artifacts, logs, support bundles, and backups where appropriate. - Use a dedicated secrets-file location outside the repository and document credential rotation and revocation procedures.
- Avoid printing credential-bearing exceptions or values and add tests confirming that malformed multiline keys are rejected.
