T09 · Insecure Skill Coding Practices
- Location
SKILL.md:37- Finding
Unescaped Query Interpolation Enables JavaScript Injection
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, line 37; the same unsafe pattern is repeated at lines 69 and 173
Vulnerability Type: JavaScript injection through unescaped query interpolation
Risk Level: MediumVulnerable Code:
javascript "fn": "(() => { const editor = document.querySelector('[contenteditable=\"true\"]'); if(editor) { editor.focus(); editor.innerText = 'YOUR_QUERY_HERE'; return 'typed'; } return 'not found'; })()"Related examples repeat the same construction:
javascript "fn": "(() => { const e = document.querySelector('[contenteditable=\"true\"]'); if(e) { e.focus(); e.innerText = 'What is quantum computing?'; return 'ok'; } return 'fail'; })()"javascript "fn":"(() => { const e = document.querySelector('[contenteditable=\"true\"]'); e.focus(); e.innerText = 'Explain quantum entanglement briefly'; return 'ok'; })()"Technical Analysis
The skill tells an agent to replace
YOUR_QUERY_HEREwith query content inside a single-quoted JavaScript string and then execute the generated source through the browser'sevaluateoperation. It does not require the query to be escaped or serialized first.If attacker-controlled query text contains a single quote followed by valid JavaScript syntax, it can terminate the intended string literal and introduce additional statements. Because the resulting source is passed to
evaluate, those statements execute in the context of the currently authenticated Grok page rather than being treated exclusively as text.Assigning data to
innerTextis ordinarily safe, but that protection does not apply here because the untrusted value is first interpolated into executable JavaScript source. The injection occurs before theinnerTextassignment is evaluated.Attack Path
- An attacker supplies or influences a query that contains a string terminator and additional JavaScript syntax.
- An agent follows the documented work ...[truncated 1583 chars]
- Remediation
View remediation
Remediation Suggestions
Do not concatenate query content into JavaScript source. Apply the following hardening measures:
- Prefer a browser automation typing or fill operation that accepts the query as data and does not evaluate generated JavaScript.
- If
evaluateis unavoidable, pass the query as a separately serialized argument supported by the browser automation interface. - Where argument passing is unavailable, serialize the complete query with a trusted JSON serializer such as
JSON.stringifybefore incorporating it into the expression. Do not perform manual quote replacement. - Update every occurrence of this pattern, including lines 37, 69, and 173.
- Document that raw user input must never be substituted into executable source templates.
- Add tests using quotes, backslashes, line separators, template delimiters, and attempted statement injection to verify that all supplied content remains inert text.
- Use a dedicated, least-privileged browser profile without unrelated authenticated tabs or sensitive session data to reduce impact if browser automation is compromised.
A safer conceptual implementation passes the query as data:
javascript (query) => { const editor = document.querySelector('[contenteditable="true"]'); if (!editor) return 'not found'; editor.focus(); editor.innerText = query; return 'typed'; }The automation API should supply
queryas an argument rather than embedding it into the function's source code.
