T09 · Insecure Skill Coding Practices
- Location
- scripts/config.py:14
- Finding
- Plaintext API Key Persistence and Configurable Credential Destination<![CDATA[ ## Vulnerability Details **File Location**: `scripts/config.py:14-62`, `scripts/call_api.py:49-72` **Vulnerability Type**: Plaintext secret storage and unsafe configurable outbound endpoint **Risk Level**: Medium ### Vulnerable Code ```python class Settings(BaseSettings): """小笨羊高考Skill配置""" model_config = SettingsConfigDict( env_prefix="XBY_GAOKAO_", env_file=".env", env_file_encoding="utf-8", extra="ignore", ) # API配置 base_url: str = "https://mcp.xiaobenyang.com" mcp_id: str = "1820705335657482" api_key: str = "" # 超时和重试配置 timeout_seconds: float = 30.0 max_retries: int = 2 # 数据配置 default_year: int = 2025 def model_post_init(self, __context): # 强制从 .env 文件读取 XBY_APIKEY env_path = Path(".env") if env_path.exists(): content = env_path.read_text(encoding="utf-8") for line in content.splitlines(): if line.startswith("XBY_APIKEY="): self.api_key = line.split("=", 1)[1].strip() break # 如果环境变量有值,覆盖 .env 的值 env_val = os.getenv("XBY_APIKEY", "") if env_val: self.api_key = env_val 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( ...[truncated 3143 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Store the API key in an operating-system credential manager or managed secrets service rather than a project-local plaintext file. 2. If `.env` persistence must remain supported: - Create the file atomically. - Set its mode explicitly to `0600`. - Verify ownership and permissions before reading or updating it. - Refuse to use symlinked or non-regular `.env` files. - Ensure `.env` is excluded from version control, packaging, logs, and backups. 3. Remove production support for overriding `base_url` through an untrusted environment. 4. If endpoint configuration is required, validate the parsed URL: - Require HTTPS. - Permit only an explicit hostname allowlist such as `mcp.xiaobenyang.com`. - Reject embedded credentials, unexpected ports, IP-literal destinations, and malformed URLs. 5. Disable redirects or validate every redirect destination before forwarding authentication headers or request bodies. 6. Warn users clearly that driving-license data is transmitted to a third-party OCR service and obtain appropriate consent before submission. 7. Rotate any API key that may have been stored with permissive file permissions or used while the endpoint configuration was untrusted. ]]>
