T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:45- Finding
Plaintext API Key Persistence and Configurable Credential Destination
- Content
View full analysis
Vulnerability Details
File Location:
scripts/config.py:18-25, 45-63, 70-78;scripts/call_api.py:49-78;SKILL.md:13-20, 32-38
Vulnerability Type: Plaintext secret storage and insufficient validation of a credential-bearing endpoint
Risk Level: MediumVulnerable Code
scripts/config.py:18-25:python # API配置 base_url: str = "https://mcp.xiaobenyang.com" mcp_id: str = "1820705335657482" api_key: str = "" # 超时和重试配置 timeout_seconds: float = 30.0 max_retries: int = 2scripts/config.py:45-63: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 Truescripts/config.py:70-78:python def set_api_key(api_key: str) -> bool: """设置API key并持久化到.env""" if not api_key or not api_key.strip(): return False api_key = api_key.strip() if not save_api_key_to_env(api_key): return False # 更新全局 settings 实例 settings.api_key = api_keyscripts/call_api.py:49-78:python def call_tool( self, mcp_id: str, tool_name: str, params: dict[str, Any], ) -> HttpResult: """调用小笨羊MCP工具""" url = f"{settings.base_url}/api" mcp_id = mcp_id or settings.mcp_id api_key = get_api_key() if not api_key: ...[truncated 4062 chars]- Remediation
View remediation
Remediation Suggestions
- Do not persist API keys by default. Keep the key in memory for the current session or retrieve it from an operating-system credential store or managed secret service.
- If file persistence is explicitly approved, place the secret in a dedicated configuration directory and create the file atomically with owner-only permissions, such as mode
0600on POSIX systems. - Warn users before persistent storage and document the exact storage location, retention behavior, and deletion procedure.
- Prevent the secret file from entering source control by supplying an appropriate
.gitignorerule, while recognizing that this does not replace filesystem access controls. - Make the production API origin immutable where practical. Otherwise, validate it before attaching credentials:
- Require the
httpsscheme. - Require an exact approved hostname.
- Reject embedded credentials, unexpected ports, and unapproved redirects.
- Require the
- Disable redirects for credential-bearing requests or revalidate every redirect destination before forwarding sensitive headers.
- Do not mount or support plaintext HTTP for authenticated production requests.
- Separate endpoint configuration from credential handling so an untrusted environment variable cannot choose where a sensitive header is sent.
- Consider implementing elementary calculator operations locally, eliminating the need to transmit operands or require a remote API credential.
- Rotate any API key that may already have been stored in a broadly accessible
.envfile or sent while the endpoint configuration was untrusted.
