T09 · Insecure Skill Coding Practices
- Location
index.js:14- Finding
Untrusted JavaScript Evaluation Without Resource Limits
- Content
View full analysis
Vulnerability Details
File Location:
index.js:14-26
Vulnerability Type: Untrusted code evaluation and denial of service
Risk Level: HighVulnerable Code
js const sandbox = {}; const script = new vm.Script('result = (' + content + ')'); const context = vm.createContext(sandbox); script.runInContext(context); const result = sandbox.result; if (typeof result === 'function' || typeof result === 'symbol' || typeof result === 'undefined') { throw new Error('Result is not serializable data (function/symbol/undefined)'); } return JSON.stringify(result, null, 2);Technical Analysis
When standard JSON parsing fails, file contents are concatenated into a JavaScript expression and executed through Node.js
vm.Script. The input is therefore treated as executable JavaScript rather than data.The empty VM context limits ordinary access to host globals, but Node.js does not document
node:vmas a security mechanism for running hostile code. More directly,script.runInContext(context)has no timeout. An attacker can supply an immediately invoked function containing an infinite loop and block the process indefinitely.The top-level type check does not make the resulting object safe. The evaluated expression can create nested functions, getters, proxies, or a
toJSONmethod. Such behavior may execute later whenJSON.stringifytraverses the result. Serialization itself has no timeout or resource limit.The assertion in
SKILL.mdthat the VM ensures no access to the global scope or process overstates the security guarantee and could cause callers to process untrusted files under an unsafe assumption.Attack Path
- An attacker creates or modifies a
.jsonfile that is invalid underJSON.parsebut valid as a JavaScript expression. - A user invokes the utility directly with
--file, or the recursive scanner encounters the file. JSON.parsefails, causing execution to fall back tovm.Script.- The malicious expressi ...[truncated 950 chars]
- An attacker creates or modifies a
- Remediation
View remediation
Remediation Suggestions
- Remove JavaScript evaluation entirely and use a non-executing parser designed for JSON5, JSONC, or another explicitly supported loose-data grammar.
- Pin and audit any parser dependency before adding it to the package.
- Define the accepted syntax narrowly instead of accepting arbitrary JavaScript expressions.
- If VM evaluation must temporarily remain:
- Set a short
timeoutonrunInContext. - Disable string and WebAssembly code generation when creating the context.
- Run parsing in a separate resource-limited worker process.
- Enforce memory and CPU limits externally.
- Reject functions, accessors, proxies, custom prototypes, and
toJSONmethods throughout the complete object graph. - Copy accepted values into plain, null-prototype data structures before serialization.
- Set a short
- Add adversarial tests for infinite loops, deeply nested input, getters, proxies,
toJSON, excessive allocation, and known VM escape patterns. - Revise
SKILL.mdso it does not characterizenode:vmas a security sandbox.
