T09 · Insecure Skill Coding Practices
- Location
publish-asset-v2.js:60- Finding
Node bearer secret stored without restrictive file permissions
- Content
View full analysis
Vulnerability Details
File Location:
publish-asset-v2.js:60-63
Vulnerability Type: Plaintext credential storage with unsafe default permissions
Risk Level: MediumVulnerable Code
js const saveNodeSecret = (secret) => { const secretFile = path.join(__dirname, '.node_secret'); fs.writeFileSync(secretFile, secret); };Technical Analysis
The node bearer credential is stored in plaintext through
fs.writeFileSyncwithout an explicit restrictive file mode. For a newly created file, Node.js uses a default mode subject to the process umask. In environments with a permissive umask, the resulting.node_secretfile may be readable by other local users or processes.The implementation also does not verify whether
.node_secretis a symbolic link before writing. If an attacker can modify the Skill directory, this may permit an unintended file overwrite, although such an attacker already requires local write access to that directory.Sending this secret to the declared EvoMap publishing endpoint as an Authorization token is necessary for the advertised functionality. The vulnerability concerns its local storage rather than confirmed network exfiltration.
Attack Path
- A user runs
publish-asset-v2.js. - The Skill registers the node and receives a
node_secretfrom EvoMap. - The secret is written to
.node_secretusing default filesystem permissions. - Another local account or process with file-read access obtains the credential.
- The attacker submits authenticated requests to the EvoMap API using the stolen bearer secret.
- The attacker may impersonate the registered node and publish assets under its identity.
Impact Assessment
Exploitation can expose the node's authentication credential. The attacker obtains the API privileges assigned to that node, principally the ability to authenticate and publish assets. The issue does not directly grant operating-system priv ...[truncated 52 chars]
- A user runs
- Remediation
View remediation
Remediation Suggestions
- Create the secret file with owner-only permissions:
js fs.writeFileSync(secretFile, secret, { mode: 0o600, flag: 'w' }); fs.chmodSync(secretFile, 0o600); - Inspect the destination with
lstatSyncand reject symbolic links before writing. - Store the credential in an operating-system credential manager where available.
- Avoid placing the secret in shared, archived, or source-controlled directories.
- Add
.node_secretand.node_idto.gitignore. - Document the credential's scope, rotation policy, and revocation procedure.
- Create the secret file with owner-only permissions:
