T09 · Insecure Skill Coding Practices
Error
- Location
- canvas-inject.py:18
- Finding
- JavaScript Injection Through Incomplete Template-Literal Escaping<![CDATA[ ## Vulnerability Details **File Location**: `canvas-inject.py:18-25` **Additional Locations**: `CANVAS-LOADING.md:40-50`, `SKILL.md:131-139` **Vulnerability Type**: JavaScript code injection caused by unsafe code generation **Risk Level**: High ### Vulnerable Code ```python # Escape backticks in HTML (they break the JS template literal) html_escaped = html_content.replace('`', '\\`') # JavaScript to inject HTML js_code = f"""document.open(); document.write(`{html_escaped}`); document.close();""" ``` The same unsafe construction is recommended in the documentation: ```python html_escaped = html_content.replace('`', '\\`') js_code = f"""document.open(); document.write(`{html_escaped}`); document.close();""" ``` ### Technical Analysis The helper embeds `html_content` inside a JavaScript template literal but escapes only backtick characters. It does not neutralize JavaScript template-literal interpolation sequences such as `${...}`, nor does it robustly encode backslashes and other JavaScript-significant input. Consequently, attacker-controlled HTML containing a value such as `${maliciousExpression()}` is interpreted as JavaScript during evaluation rather than being treated exclusively as document content. The generated string is subsequently sent to the Canvas `eval` operation, providing a direct execution sink. Although the intended feature permits rendering active HTML, this flaw causes input to execute while the privileged injection program is being evaluated, before normal document parsing and outside the expected data boundary. ### Attack Path 1. An attacker influences HTML passed to `inject_html_to_canvas()`, for example through externally sourced content used to construct a dashboard. 2. The HTML includes a JavaScript template-literal interpolation expression such as `${...}`. 3. The helper escapes backticks but leaves the interpolation expression intact. 4. The returned `step2_inject` command is submitted to Canvas `eval`. 5. Canvas ...[truncated 632 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Do not place HTML inside a JavaScript template literal. Serialize the content as a JavaScript string using a standards-compliant encoder: ```python import json js_code = ( "document.open();" f"document.write({json.dumps(html_content)});" "document.close();" ) ``` Additional hardening should include: 1. Treat externally sourced HTML as untrusted. 2. Sanitize HTML with an allowlist-based sanitizer if scripts and active attributes are not required. 3. Prefer a structured Canvas API that accepts HTML as data instead of generating JavaScript. 4. Remove the unsafe template-literal example from `CANVAS-LOADING.md` and `SKILL.md`. 5. Add regression tests covering backticks, `${...}`, backslashes, Unicode separators, closing script tags, and malformed HTML. ]]>
