T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:47- Finding
API Key Persisted in a Plaintext File Without Enforced Access Controls
- Content
View full analysis
Vulnerability Details
File Location:
scripts/config.py, lines 47-62
Vulnerability Type: Plaintext credential storage and unsafe configuration-file handling
Risk Level: Mediumpython 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 supplied API key is persisted directly in a plaintext
.envfile. The implementation does not create the file with restrictive permissions, verify the permissions of an existing file, or correct overly permissive permissions after writing.The file path is relative to the process working directory rather than anchored to a controlled, Skill-specific configuration directory. Consequently, the secret may be written into an unexpected project or shared directory. The implementation also does not reject symbolic links or use an atomic, securely created temporary file, so a locally prepared
.envpath could redirect the write to another file that the running process is permitted to modify.The API key is additionally placed into the process environment. Although this is often required for configuration, it expands the set of process-level mechanisms through which the credential may become visible.
Attack Path
- The user supplies an API key as required by the Skill workflow.
set_api_key()invokes the affected persistence function.- The function writes the key as
XBY_APIKEY=<secret>into./.env. ...[truncated 1077 chars]
- Remediation
View remediation
Remediation Suggestions
- Prefer an operating-system credential manager, deployment secret manager, or environment-only configuration instead of plaintext persistence.
- If file persistence is unavoidable, use a dedicated absolute configuration path owned by the current user rather than the process working directory.
- Create new credential files with mode
0600and verify or correct the permissions of existing files before reading or writing them. - Reject symbolic links and verify that the resolved destination remains inside the expected configuration directory.
- Write updates atomically through a securely created temporary file in the same directory, apply restrictive permissions, and then replace the destination.
- Add
.envto.gitignoreand other packaging or backup exclusion rules. - Avoid placing the key in the process environment unless required by the execution model.
- Rotate any API key that may already have been stored in a shared, world-readable, or committed
.envfile.
