T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/sts_create.py:146
- Finding
- Plaintext Alibaba Cloud credentials are persistently cached on disk<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sts_create.py:146-177` **Vulnerability Type**: Plaintext credential storage **Risk Level**: High ### Vulnerable Code ```python def save_credentials_to_cache(uid: str, result: dict): """ Write credentials to local cache. Multi-UID coexistence: - Overwrite/add entry for current UID, keep other UIDs unchanged - Also clean up expired entries for other UIDs """ if not result.get('success') or not uid: return cache = _read_cache_file() credentials = cache.get('credentials', {}) or {} credentials = { k: v for k, v in credentials.items() if k == str(uid) or _is_credential_valid(v) } credentials[str(uid)] = { 'access_key_id': result.get('access_key_id'), 'access_key_secret': result.get('access_key_secret'), 'security_token': result.get('security_token'), 'expiration': result.get('expiration'), 'cached_at': datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"), } payload = {'last_active_uid': str(uid), 'credentials': credentials} try: with open(STS_CACHE_FILE, 'w', encoding='utf-8') as f: json.dump(payload, f, indent=2, ensure_ascii=False) os.chmod(STS_CACHE_FILE, 0o600) except OSError as e: print(f"Warning: Cache write failed: {e}", file=sys.stderr) ``` ### Technical Analysis The function stores the full Alibaba Cloud access-key ID, access-key secret, and optional STS security token in an unencrypted JSON file at `scripts/.sts_cache.json`. File mode `0600` limits access to the owning operating-system account, but it does not protect credentials from: - Other Skills, plugins, or processes executing as the same user. - Malware or a compromised development tool running under that account. - Insecure backups, snapshots, or artifact collection. - Accidental packaging of the cache file. - Local privilege escalation or compromise of the owning account. ...[truncated 1809 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not persist static access-key secrets. Keep credentials in process memory and pass an authenticated client object through the workflow. 2. Require short-lived STS credentials with a maximum lifetime appropriate for one diagnostic session, preferably no more than 3,600 seconds. 3. If caching is unavoidable, use an operating-system credential store such as Keychain, Secret Service, or Windows Credential Manager rather than plaintext JSON. 4. Create any unavoidable cache atomically with restrictive permissions at creation time, for example by using `os.open` with mode `0o600`, writing to a secure temporary file, and atomically renaming it. 5. Reject credentials without an expiration for local caching. 6. Delete cached credentials immediately after the diagnostic workflow completes and provide explicit cleanup on exceptions and interrupts. 7. Ensure `.sts_cache.json` is excluded from source control, packages, backups, diagnostic bundles, and support artifacts. 8. Warn users not to run the Skill with owner or broadly privileged cloud credentials. ]]>
