T09 · Insecure Skill Coding Practices
- Location
scripts/gen_sts.py:84- Finding
Predictable and Insecurely Created Temporary STS Credential Files
- Content
View full analysis
Vulnerability Details
File Location:
scripts/gen_sts.py, lines 84–85 and 110–118
Vulnerability Type: Insecure temporary-file handling and plaintext credential exposure
Risk Level: MediumVulnerable Code
python creds_out = args.creds_out or str(Path(tempfile.gettempdir()) / "sts-creds.json") sh_out = args.sh_out or str(Path(tempfile.gettempdir()) / "sts-creds.sh")python camel = { "accessKeyId": c["credentials"]["access_key_id"], "secretAccessKey": c["credentials"]["secret_access_key"], "securityToken": c["credentials"]["security_token"], "_refresh": {"accountId": args.account, "agencyUrn": agency_urn, "region": args.region, "hcloudExe": hcloud_exe}, } Path(creds_out).write_text(json.dumps(camel, indent=2, ensure_ascii=False), encoding="utf-8") Path(sh_out).write_text( f"export STS_AK='{c['credentials']['access_key_id']}'\n" f"export STS_SK='{c['credentials']['secret_access_key']}'\n" f"export STS_TOKEN='{c['credentials']['security_token']}'\n", encoding="utf-8", )Technical Analysis
The default output paths are fixed, predictable names in the shared operating-system temporary directory:
sts-creds.jsonandsts-creds.sh. Both files contain active STS access keys, secret keys, and security tokens in plaintext.The files are written with
Path.write_text(), which does not enforce owner-only permissions, exclusive creation, or symbolic-link rejection. The effective permissions depend on the process umask. On a multi-user system, a permissive umask may expose the credentials to another local account.The predictable names also permit a local attacker to pre-create either path as a symbolic link. When the victim runs Step 1 of the documented publishing workflow,
write_text()follows the link and truncates the linked destination if it is writable by the victim. This creates both a credential-disclosure opportunity and a limited arbitrary-file-overwrite primitive under the victim's pe ...[truncated 1476 chars]- Remediation
View remediation
Remediation Suggestions
- Create a unique private directory for each invocation using
tempfile.mkdtemp()ortempfile.TemporaryDirectory(), and enforce mode0700. - Create credential files atomically with owner-only mode
0600, usingos.open()withO_CREAT | O_EXCL; addO_NOFOLLOWwhere supported. - Reject symbolic links and verify that any caller-supplied output target is a regular file in an authorized directory.
- Set restrictive permissions explicitly rather than relying on the process umask.
- Avoid generating
sts-creds.shunless it is strictly required. Prefer passing credentials through a protected file descriptor or private credential file. - Delete temporary credential files in a
finallyblock immediately after the publishing operation finishes or fails. - Use unique filenames even inside the private directory to prevent collisions between concurrent executions.
- Create a unique private directory for each invocation using
