T09 · Insecure Skill Coding Practices
Error
- Location
- assets/review-template.html:141
- Finding
- Unsafe Model JSON Injection Allows Script Execution in Generated Review Reports<![CDATA[ ## Vulnerability Details **File Location**: `assets/review-template.html:141` and `assets/review-template.html:353`; the unsafe generation workflow is specified at `references/review.md:28` **Vulnerability Type**: Stored HTML injection / cross-site scripting through unsafe JSON embedding **Risk Level**: High ### Vulnerable Code `references/review.md:28`: ```text Generate compact model JSON and inject it into `assets/review-template.html`. ``` `assets/review-template.html:141`: ```html <script type="application/json" id="model">/*__MODEL_JSON__*/</script> ``` `assets/review-template.html:350-354`: ```html <script> function App(){ var model = JSON.parse(document.getElementById('model').textContent); ``` ### Technical Analysis The workflow instructs the agent to insert generated model JSON directly into a `script` element. It does not require context-aware serialization, escaping, or validation before replacement of the `/*__MODEL_JSON__*/` marker. Although the element uses the non-executable `application/json` MIME type, its contents are still parsed under HTML script-element parsing rules. An attacker-controlled string containing `</script>` can terminate the JSON container before `JSON.parse` runs. The remaining content is then interpreted as HTML and may introduce an executable `script` element or another active HTML construct. This is relevant because the model is derived from externally supplied REST/OpenAPI descriptions, CLI contracts, DDL, CSV metadata, evidence text, and related interface documentation. Those sources may contain attacker-controlled descriptions, names, examples, or other textual values that are copied into the review model. Normal JSON serialization alone is insufficient because JSON permits a literal `<` character in strings. The HTML parser recognizes the closing `</script>` sequence without considering whether it appears inside a JSON string. ### Attack Path 1. An attacker supplies or modifies an interface cont ...[truncated 1688 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Use HTML-safe JSON serialization.** Before embedding serialized JSON in a script element, escape characters that can affect HTML parsing: ```javascript const safeJson = JSON.stringify(model) .replace(/</g, '\\u003c') .replace(/>/g, '\\u003e') .replace(/&/g, '\\u0026') .replace(/\u2028/g, '\\u2028') .replace(/\u2029/g, '\\u2029'); ``` At minimum, ensure that no literal case-insensitive `</script` sequence can occur in the embedded content. 2. **Document the required serialization procedure.** Update `references/review.md` so agents must use a defined context-aware encoder rather than performing unrestricted string replacement. 3. **Prefer a safer data-loading design.** Store validated model JSON in a separate local `.json` file and load it through a controlled mechanism where deployment constraints permit. If a self-contained report is mandatory, use the HTML-safe serialization approach above. 4. **Validate generated reports.** After injection, verify that the document contains exactly the expected script elements and that the model element remains structurally intact. 5. **Add regression tests** using hostile values such as: ```text </script><script>alert(1)</script> </ScRiPt><img src=x onerror=alert(1)> ``` Confirm that these values are displayed as text and cannot create DOM elements or execute code. 6. **Add a restrictive Content Security Policy.** Refactor inline scripts to use an external local script or an approved hash, then apply a policy such as: ```http Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; connect-src 'none'; object-src 'none'; base-uri 'none' ``` CSP should be treated as defense in depth, not as a replacement for safe serialization. ]]>
