T09 · Insecure Skill Coding Practices
Error
- Location
- eval-viewer/generate_review.py:149
- Finding
- Stored Script Injection Through Embedded Evaluation Outputs<![CDATA[ ## Vulnerability Details **File Location**: `eval-viewer/generate_review.py:149-211, 267-274`; injection sink in `eval-viewer/viewer.html:646-650` **Vulnerability Type**: Stored HTML/JavaScript injection **Risk Level**: High ### Vulnerable Code ```python def embed_file(path: Path) -> dict: """Read a file and return an embedded representation.""" ext = path.suffix.lower() mime = get_mime_type(path) if ext in TEXT_EXTENSIONS: try: content = path.read_text(errors="replace") except OSError: content = "(Error reading file)" return { "name": path.name, "type": "text", "content": content, } elif ext in IMAGE_EXTENSIONS: try: raw = path.read_bytes() b64 = base64.b64encode(raw).decode("ascii") except OSError: return {"name": path.name, "type": "error", "content": "(Error reading file)"} return { "name": path.name, "type": "image", "mime": mime, "data_uri": f"data:{mime};base64,{b64}", } elif ext == ".pdf": try: raw = path.read_bytes() b64 = base64.b64encode(raw).decode("ascii") except OSError: return {"name": path.name, "type": "error", "content": "(Error reading file)"} return { "name": path.name, "type": "pdf", "data_uri": f"data:{mime};base64,{b64}", } elif ext == ".xlsx": try: raw = path.read_bytes() b64 = base64.b64encode(raw).decode("ascii") except OSError: return {"name": path.name, "type": "error", "content": "(Error reading file)"} return { "name": path.name, "type": "xlsx", "data_b64": b64, } else: # Binary / unknown — base64 download link try: raw = path.read_bytes() b ...[truncated 3302 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not insert serialized untrusted data directly into an executable script element. 2. Store the serialized data in a non-executable element: ```html <script id="embedded-data" type="application/json"> SAFE_JSON_DATA </script> ``` 3. Before embedding JSON into HTML, encode HTML-significant characters, at minimum: ```python data_json = json.dumps(embedded) data_json = ( data_json .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("&", "\\u0026") ) ``` 4. Parse the non-executable element at runtime: ```javascript const EMBEDDED_DATA = JSON.parse( document.getElementById("embedded-data").textContent ); ``` 5. Add a restrictive Content Security Policy that disallows arbitrary inline scripts and limits outbound connections, for example by using a nonce-bearing local script and `connect-src 'self'`. 6. Prefer serving downloadable output files through validated local endpoints instead of embedding every file into the page. 7. Add regression tests using payloads containing `</script>`, mixed-case `</ScRiPt>`, HTML comments, Unicode separators, and malicious SVG/HTML content. ]]>
