T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/config.py:43
- Finding
- API Key Stored in an Unprotected Plaintext Environment File## Vulnerability Details **File Location**: `scripts/config.py:43-62` **Vulnerability Type**: Plaintext credential storage and environment-file injection **Risk Level**: Medium ### Vulnerable 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 False ``` ### Technical Analysis The function persists an API credential as plaintext in a relative `.env` file. It does not explicitly set restrictive file permissions, so the effective permissions depend on the host's umask and any permissions already assigned to the file. The relative path also causes the secret to be written into the process's current working directory rather than a dedicated, controlled configuration directory. This can result in the credential being stored in an unrelated repository, included in backups, or accidentally committed to version control. The function also interpolates `api_key` directly into dotenv content without rejecting embedded carriage-return or newline characters. Although `set_api_key()` strips leading and trailing whitespace, it does not remove internal newline characters. A caller able to control the submitted key can therefore add additional dotenv entries. Those injected ...[truncated 1909 chars]
- Remediation
- ## Remediation Suggestions 1. Prefer an operating-system credential store, deployment secret manager, or platform-provided secret facility instead of writing credentials to a project file. 2. If file persistence is required, use a fixed Skill-specific configuration directory rather than the current working directory. 3. Create the secret file atomically with owner-only permissions such as `0600`, and verify existing file ownership and permissions before updating it. 4. Reject API keys containing `\r`, `\n`, NUL characters, or characters outside the provider's documented key format. 5. Escape values using a standards-compliant dotenv serializer if arbitrary values must be supported. 6. Ensure `.env` is excluded from version control, build artifacts, diagnostic bundles, and backups that do not require it. 7. Avoid printing or logging credential values, and document a credential-rotation procedure for suspected disclosure.
