T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:46- Finding
API Key Stored in a Plaintext Environment File Without Enforced Access Controls
- Content
View full analysis
Vulnerability Details
File Location:
scripts/config.py, lines 46–65
Vulnerability Type: Plaintext credential storage with uncontrolled 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.Path.write_text()creates the file according to the process umask and does not explicitly enforce owner-only permissions. If the file already exists with permissive permissions, those permissions are retained.The implementation also does not use an operating-system credential store, atomic secure file creation, or checks preventing the credential file from being committed to source control. Consequently, the credential may be exposed to other local accounts, backups, development tooling, or repository history.
Because the value is later used as the
XBY-APIKEYauthentication header when communicating with the configured API, disclosure permits reuse of the credential outside the Skill.Attack Path
- A user supplies an API key through the documented Skill workflow.
set_api_key()invokessave_api_key_to_env().- The function writes `XBY_APIKEY=< ...[truncated 941 chars]
- Remediation
View remediation
Remediation Suggestions
- Prefer an operating-system credential manager or a session-only environment variable instead of persistent plaintext storage.
- If file persistence is unavoidable, create the credential file atomically with owner-only permissions such as
0600. - Explicitly correct permissions on an existing
.envfile before writing secrets to it. - Reject carriage returns and newline characters in the supplied key to prevent additional environment-file entries from being injected.
- Add
.envto.gitignoreand provide only a secret-free.env.example. - Avoid including credentials in logs, exceptions, backups, diagnostic output, or returned API data.
- Document credential rotation and revocation procedures in case the file is exposed.
- Consider storing only a reference to a credential managed by the deployment environment rather than the credential itself.
