T09 · Insecure Skill Coding Practices
- Location
index.js:5- Finding
Predictable Temporary File Allows File Destruction and Symlink-Based Target Corruption
- Content
View full analysis
Vulnerability Details
File Location:
index.js, line 5
Vulnerability Type: Unsafe temporary-file creation and predictable filename
Risk Level: Mediumjs for(const d of dirs){const abs=path.resolve(d); const exists=fs.existsSync(abs); let writable=false; if(exists){ try{ const test=path.join(abs,'.env-health-check.tmp'); fs.writeFileSync(test,'ok','utf8'); fs.unlinkSync(test); writable=true; }catch{} }Technical Analysis
The directory write-permission test uses the fixed filename
.env-health-check.tmp.fs.writeFileSync()opens an existing destination for truncation and does not require exclusive creation. Consequently, if a regular file already exists at that path, the skill replaces its contents withokand then deletes it.The operation also does not prevent symbolic-link traversal. If an attacker places
.env-health-check.tmpas a symbolic link,fs.writeFileSync()follows the link and truncates the linked target. The subsequentfs.unlinkSync(test)removes the symbolic link itself, but the target remains corrupted.Because the filename is predictable and the existence check does not securely validate the probe file, this creates a time-of-check/time-of-use and unsafe temporary-file condition.
Attack Path
- An attacker obtains write access to a directory that a more privileged user or service will pass through
--dir. - The attacker creates
<checked-directory>/.env-health-check.tmpas either:- a valuable regular file, or
- a symbolic link to another file writable by the account running the skill.
- The privileged user or service invokes
node index.js --dir <checked-directory>. - The skill follows or opens the predictable pathname and truncates its destination to the string
ok. - The skill deletes
.env-health-check.tmp. If it was a symbolic link, the link is removed while the linked target remains corrupted.
Impact Assessment
Exploitation does not d ...[truncated 582 chars]
- An attacker obtains write access to a directory that a more privileged user or service will pass through
- Remediation
View remediation
Remediation Suggestions
- Create a unique probe in the target directory using a cryptographically random name or
fs.mkdtempSync(). - Open the probe atomically with exclusive creation, such as
O_CREAT | O_EXCL | O_WRONLY, so an existing path is never overwritten. - Where supported, add
O_NOFOLLOWto prevent symbolic-link traversal. - Record whether the current invocation successfully created the probe and delete it only if ownership is certain.
- Place cleanup in a
finallyblock so failures do not leave probe files behind. - Do not perform a separate existence check followed by a non-exclusive write, because that remains vulnerable to races.
- Consider using
fs.accessSync(abs, fs.constants.W_OK)when a non-destructive permission indication is sufficient, while recognizing that an actual atomic probe more accurately tests effective write access.
- Create a unique probe in the target directory using a cryptographically random name or
