T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:46- Finding
API Key Stored in a Plaintext File Without Enforced Access Restrictions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/config.py:46-65
Vulnerability Type: Plaintext credential storage with unsafe file permissions
Risk Level: MediumVulnerable 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 TrueTechnical Analysis
The function persistently writes the user-supplied API key into a plaintext
.envfile in the process's current working directory. It does not explicitly set restrictive file permissions, verify file ownership, use a protected application-specific credential directory, or prevent symbolic-link traversal.For a newly created file, effective permissions depend on the operating system and the process umask. If
.envalready exists, its potentially permissive permissions are retained. Storing the file relative to the current working directory also increases the possibility that it resides in a shared directory, becomes part of a source archive, or is accidentally committed to version control.The direct use of
Path.write_text()is also non-atomic. Although not independently classified here, concurrent writes or interruption could damage the configuration file.Attack Path
- The Skill requests an API key from the user.
- The supplied key is passed to `set_api ...[truncated 1202 chars]
- Remediation
View remediation
Remediation Suggestions
- Prefer session-only credential handling or an operating-system credential manager instead of persistent plaintext storage.
- If file persistence is essential, store credentials in a dedicated per-user configuration directory rather than the current working directory.
- Create the credential file atomically with owner-only permissions such as
0600, and verify its ownership and permissions before reading or updating it. - Refuse to follow symbolic links and ensure the destination is a regular file owned by the current user.
- Write updates to a securely created temporary file in the same protected directory, apply restrictive permissions, and atomically replace the destination.
- Add
.envto.gitignoreand relevant packaging or backup exclusion lists. - Document credential rotation and advise users to revoke any key that may have been stored in an exposed project directory.
- Avoid printing or returning the credential in logs, exceptions, or API responses.
