T09 · Insecure Skill Coding Practices
- Location
scripts/vtag.sh:19- Finding
Unsafe Storage of a Long-Lived OAuth Credential
- Content
View full analysis
Vulnerability Details
File Location:
scripts/vtag.sh, lines 19 and 62-65
Vulnerability Type: Unsafe credential file handling, including symbolic-link following and failure to correct existing file permissions
Risk Level: MediumVulnerable Code
bash CRED="${VTAG_CRED:-$HOME/.vtag/credentials}"bash mkdir -p "$(dirname "$CRED")" # umask 077 不是装饰:这里面是一把长期有效的只读凭证。 ( umask 077; printf '%s' "$t" > "$CRED" ) echo "已授权,站点 $(printf '%s' "$t" | _json tag_id)" >&2Technical Analysis
The script stores the complete OAuth token response, including a documented long-lived
access_token, by using ordinary shell redirection to the configured credential path.Although
umask 077protects a newly created file, it does not change the permissions of an existing file. If the credential file already exists with group-readable or world-readable permissions, the newly written token retains those unsafe permissions.Shell redirection also follows symbolic links. The script does not verify that the credential path is a regular file, reject symbolic links, securely create a temporary file, or atomically install the credential. Consequently, a pre-positioned symbolic link or a path replacement race can redirect the credential write to another file writable by the invoking user.
The default path under the user's home directory reduces exposure under normal conditions, but the weakness remains relevant when the credential file or directory already has unsafe permissions, when another local process can manipulate the path, or when
VTAG_CREDpoints to a shared or attacker-influenced location. The credential access is necessary for reusable authentication and does not itself exceed the Skill's declared read-only function; the vulnerability is in how the credential is persisted.Attack Path
- The attacker obtains the ability to prepare or replace the credential path, such as through an unsafe shared ...[truncated 1757 chars]
- Remediation
View remediation
Remediation Suggestions
-
Create and verify the credential directory with owner-only permissions:
bash cred_dir=$(dirname -- "$CRED") mkdir -p -- "$cred_dir" chmod 700 -- "$cred_dir" -
Reject symbolic links and unexpected file types before replacing an existing credential:
bash if [ -L "$CRED" ]; then echo "Refusing symbolic-link credential path" >&2 exit 1 fi if [ -e "$CRED" ] && [ ! -f "$CRED" ]; then echo "Credential path is not a regular file" >&2 exit 1 fi -
Write the response to a securely created temporary file in the same directory, apply mode
0600, validate its contents, and atomically rename it into place:bash tmp=$(mktemp "$cred_dir/.credentials.XXXXXX") trap 'rm -f -- "$tmp"' EXIT chmod 600 -- "$tmp" printf '%s' "$t" > "$tmp" [ -n "$(_json access_token < "$tmp")" ] || { echo "Credential response is invalid" >&2 exit 1 } mv -f -- "$tmp" "$CRED" chmod 600 -- "$CRED" trap - EXIT -
Validate custom
VTAG_CREDpaths. Refuse paths located in directories that are group-writable or world-writable unless the application can safely use platform-specific no-follow and exclusive-creation controls. -
Document that suspected token disclosure requires server-side revocation. Deleting the local credential file alone does not revoke the token.
-
