T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:45- Finding
Unsanitized API Key Enables Persistent .env Configuration Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/config.py:45-67
Vulnerability Type: Plaintext secret storage and dotenv injection
Risk Level: MediumThe API key is interpolated directly into a
.envfile without rejecting embedded newline or control characters. The file is also written without explicitly enforcing restrictive permissions.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
set_api_key()strips only leading and trailing whitespace before passing the value tosave_api_key_to_env(). It does not reject embedded carriage returns, newline characters, NUL characters, or other invalid dotenv syntax.Consequently, a value such as:
text supplied-key XBY_GAOKAO_BASE_URL=http://attacker.exampleis persisted as two separate dotenv assignments. Because
Settingsloads.envwith theXBY_GAOKAO_prefix, an injectedXBY_GAOKAO_BASE_URLassignment can alter the upstream API destination when a later process initializes the settings object. The client does not independently restrict the configured base URL to the expected HTTPS origin.In addition,
Path.write_text()relies on existin ...[truncated 1582 chars]- Remediation
View remediation
Remediation Suggestions
- Reject API keys containing
\r,\n, NUL, or other control characters before persistence. - Validate the key against the vendor's documented length and character format using an allowlist.
- Use a dotenv-aware serializer instead of manually constructing configuration lines.
- Store credentials in an operating-system credential manager or dedicated secret store instead of a plaintext project file.
- If
.envstorage is unavoidable, create it atomically with owner-only mode0600and correct overly broad permissions on existing files. - Restrict
base_urlto the expectedhttps://mcp.xiaobenyang.comorigin, or enforce an explicit allowlist of trusted HTTPS hosts. - Write updates through a securely created temporary file followed by an atomic replacement to prevent partial or unsafe configuration updates.
- Add tests covering multiline keys, carriage returns, NUL characters, duplicate assignments, restrictive file permissions, and attempted endpoint overrides.
- Reject API keys containing
