T09 · Insecure Skill Coding Practices
- Location
SKILL.md:40- Finding
Predictable and Insecure Temporary Cache Files
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 40–42
Vulnerability Type: Unsafe temporary file handling
Risk Level: MediumVulnerable Code
bash local f="/tmp/gh_${h}.json" local mtime; mtime=$(stat -c %Y "$f" 2>/dev/null || stat -f %m "$f" 2>/dev/null || echo 0) if [ -f "$f" ] && [ $(( $(date +%s) - mtime )) -lt 1800 ]; then cat "$f"; else gh "$@" | tee "$f"; fiThe corresponding PowerShell implementation at lines 87–91 has the same general weakness:
powershell $f = Join-Path $env:TEMP "gh_$key.json" if ((Test-Path $f) -and ((Get-Date) - (Get-Item $f).LastWriteTime).TotalMinutes -lt 30) { Get-Content $f -Raw } else { $r = gh @args | Out-String; Set-Content -Path $f -Value $r; $r }Technical Analysis
The cache filename is derived deterministically from the GitHub CLI arguments and is placed in a shared temporary directory. The implementation neither securely creates the cache file nor verifies its ownership, type, or link status before reading or writing it. It also does not explicitly enforce restrictive file permissions.
In the Bash implementation,
tee "$f"follows symbolic links. A local attacker who can derive the cache key may pre-create/tmp/gh_${h}.jsonas a symbolic link to another file writable by the Agent process. A subsequent cache miss would maketeefollow that link and overwrite the target with the GitHub response.The cache can contain responses from authenticated queries against private repositories. Depending on the process umask and temporary-directory controls, those responses may be readable by other local users. A pre-created fresh cache entry can also cause the function to return attacker-controlled content instead of querying GitHub. The PowerShell variant similarly uses a predictable path without explicit user-only ACLs or reparse-point validation.
Attack Path
- A local attacker observes or predicts the arguments supplied ...[truncated 1635 chars]
- Remediation
View remediation
Remediation Suggestions
- Store cache data in a private, per-user directory rather than directly in shared
/tmp; create that directory with mode0700. - Create cache files atomically with mode
0600, independent of the caller's umask. - Reject symbolic links and other unexpected file types, and verify that existing cache files are owned by the current user.
- Write responses to a securely created temporary file in the same private directory, then atomically rename it to the final cache path.
- Use an exclusive-create operation to prevent pre-creation races. Where available, use descriptor-relative APIs and no-follow semantics.
- On PowerShell, apply an ACL granting access only to the current user and reject reparse points before reading, writing, or replacing cache entries.
- Treat cached GitHub output as untrusted input even after filesystem hardening; validate its expected JSON structure before further Agent processing.
- Avoid caching sensitive private-repository responses unless caching is necessary, and remove cache entries when the session ends or authentication context changes.
- Store cache data in a private, per-user directory rather than directly in shared
