T09 · Insecure Skill Coding Practices
- Location
scripts/generate_images.py:23- Finding
Bearer Token Exposed Through Command-Line Arguments and Plaintext Storage
- Content
View full analysis
Vulnerability Details
File Location:
scripts/generate_images.py, lines 23–26, 99–100, and 109–115
Vulnerability Type: Plaintext credential exposure and insecure secret handling
Risk Level: HighVulnerable Code
python def get_api_key(passed_key=None): """Check for API key in environment or .env file. Prompt if missing.""" if passed_key: with open(ENV_FILE, "w") as f: f.write(f"ACEDATA_API_KEY={passed_key}\n") return passed_keypython parser.add_argument("--api_key", type=str, help="Bearer Token for AceData API.") args = parser.parse_args() token = get_api_key(args.api_key)python if not token: print("\n[!] ACEDATA_API_KEY not found.") print(f"[!] Please get your token: {SHARE_URL}") token = input("Please enter your AceData Bearer Token: ").strip() if token: with open(ENV_FILE, "w") as f: f.write(f"ACEDATA_API_KEY={token}\n") else: exit(1)Technical Analysis
The script permits an API bearer token to be supplied through the
--api_keycommand-line argument. Command-line arguments can be exposed through shell history, process inspection tools, terminal capture, automation logs, and process telemetry.Whether supplied through the argument or interactive prompt, the token is subsequently stored in a plaintext
.envfile in the Skill directory. The file is created using the process's default umask, and the implementation does not explicitly enforce owner-only permissions. The Skill also does not provide repository-exclusion controls for this generated credential file.Although persistent token storage is documented by the Skill, accepting secrets through process arguments and saving them without explicit access controls are not necessary for image generation and exceed secure least-privilege credential handling.
Attack Path
- A user invokes the documented ...[truncated 878 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove the
--api_keyoption so secrets cannot be passed through process arguments. - Prefer the
ACEDATA_API_KEYenvironment variable, an operating-system credential store, or a dedicated secret-management service. - If interactive entry is supported, use
getpass.getpass()so the token is not echoed. - Do not persist the token by default. Obtain explicit user consent before saving credentials.
- If file storage is unavoidable, create the file atomically with owner-only permissions such as mode
0600. - Add
.envto a bundled.gitignoreand document that it must never be committed, logged, or shared. - Avoid including token values in exceptions, diagnostics, or application logs.
- Recommend revocation and rotation of any token that may already have been exposed.
- Remove the
