T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:50- Finding
Transaction-Authorizing API Key and Shipping PII Stored Without Explicit Access Restrictions
- Content
View full analysis
bool: """Save credentials to credentials.json file.""" try: with open(CREDS_FILE, "w") as f: json.dump(creds, f, indent=2) return True except IOError as e: print(f"❌ Failed to save credentials: {e}", file=sys.stderr) return False ``` The data written through this function includes: ```python creds = { "api_key": result["apiKey"], "wallet_address": result["walletAddress"], "shipping_profile": { "email": args.email, "address": args.address, **({"phone": args.phone} if args.phone else {}), }, } save_credentials(creds) ``` ### Technical Analysis The Skill stores a transaction-authorizing Scout API key alongside the user's wallet address, email, physical shipping address, and optional phone number in plaintext. The file is opened using the process's default creation mode, so its effective permissions depend on the ambient `umask`. The implementation does not explicitly enforce owner-only access, check whether the destination is a symbolic link, or use atomic file replacement. The `.gitignore` entry for `credentials.json` reduces the chance of accidental Git commits, but it does not protect the file from other local users, compromised processes, overly broad backups, or filesystem synchronization tools. This is particularly sensitive because `SKILL.md` states that the API key authorizes transactions from the custodial wallet. A permissive `umask` can result in credentials readable by unintended local principals. Rewriting an existing file also preserves potentially unsafe permissions. If an attacker can pre-create or rep ...[truncated 1553 chars]- Remediation
View remediation
