T09 · Insecure Skill Coding Practices
- Location
scripts/issue-key.sh:28- Finding
Unsafe Credential File Creation Allows Disclosure and Unintended Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/issue-key.sh, lines 28-31
Vulnerability Type: Unsafe credential storage, symbolic-link following, and non-exclusive file creation
Risk Level: Highbash if [[ -n "$OUTPUT_FILE" ]]; then mkdir -p "$(dirname "$OUTPUT_FILE")" umask 077 printf '%s\n' "$TOKEN" > "$OUTPUT_FILE"Technical Analysis
The credential is written using ordinary shell redirection. This operation truncates an existing destination and follows a symbolic link if the supplied path is a symlink. It does not enforce exclusive creation or verify that the destination is a regular file owned by the current user.
Although
umask 077protects a newly created file, it does not change the permissions of an existing file. If the destination already exists with group-readable or world-readable permissions, those permissions remain in place after the new credential is written.The implementation also contradicts the documented rule in
SKILL.mdthat new keys should be saved to fresh files without overwriting old credentials by default. Exploitation requires the attacker to influence the selected output path or pre-create an entry in a directory where both the attacker and victim can write.Attack Path
- An attacker predicts or influences the credential output path.
- The attacker creates either:
- a permissively readable file at that path; or
- a symbolic link from that path to another file writable by the victim process.
- The victim runs
scripts/issue-key.shwith the affected path. - Shell redirection follows the link or truncates the existing file.
- The newly issued API credential is exposed through existing file permissions, or an unintended writable file is overwritten.
Impact Assessment
An attacker may obtain the newly issued Cryptowerk credential if it is written into a file the attacker can read. The flaw may also destroy an existing credential or ...[truncated 339 chars]
- Remediation
View remediation
Remediation Suggestions
- Refuse to overwrite an existing destination unless the user explicitly requests replacement.
- Reject symbolic links and require the destination to be a regular file.
- Create the credential file atomically with exclusive creation and mode
0600. - Set
umask 077before creating any credential-related filesystem objects. - Use a safe implementation such as Python
os.open()withO_CREAT | O_EXCL | O_WRONLYand, where supported,O_NOFOLLOW. - Write the credential completely, flush it, and close the file before reporting success.
- If replacement is supported, write to an exclusively created temporary file in the same trusted directory and use a controlled atomic rename after validating the destination.
- Require that the parent directory is trusted and not writable by untrusted users.
