T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/config.py:42
- Finding
- API Key Persisted in a Plaintext Working-Directory File<![CDATA[ ## Vulnerability Details **File Location**: `scripts/config.py:42-59` **Vulnerability Type**: Plaintext sensitive-data storage **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 API key is written without encryption to a relative `.env` file in the current working directory. The implementation does not explicitly create the file with owner-only permissions or verify the permissions of an existing file. Its effective access controls therefore depend on the process umask, existing file permissions, directory permissions, and deployment environment. Using a relative path also means the credential location depends on the directory from which the process is started. This may cause the key to be stored in an unintended shared directory, included in a backup or source archive, or exposed to other local users and processes. ### Attack Path 1. A user supplies an API key as required by the Skill. 2. `set_api_key()` invokes `save_api_key_to_env()`. 3. The function writes the key as `XBY_APIKEY=<secret>` to `.env` in the current working directory. 4. An attacker with read access to that directory or file reads the plaintext key. 5. The attacke ...[truncated 628 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Prefer an operating-system secret manager, container secret mount, or session-only in-memory credential instead of persistent plaintext storage. 2. If file persistence is unavoidable, 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 or correct the permissions of an existing file before writing. 4. Ensure `.env` is excluded from version control, build artifacts, diagnostic bundles, and backups that do not require the credential. 5. Document credential rotation and immediately revoke keys suspected of exposure. 6. Avoid returning or logging the key in exception details, diagnostics, or user-facing output. ]]>
