T09 · Insecure Skill Coding Practices
- Location
eval-viewer/generate_review.py:275- Finding
Stored JavaScript Injection in Generated Evaluation Viewer
- Content
View full analysis
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, } ``` ```python embedded = { "skill_name": skill_name, "runs": runs, "previous_feedback": previous_feedback, "previous_outputs": previous_outputs, } if benchmark: embedded["benchmark"] = benchmark data_json = json.dumps(embedded) return template.replace( "/*__EMBEDDED_DATA__*/", f"const EMBEDDED_DATA = {data_json};" ) ``` Relevant unsafe HTML construction in `viewer.html` includes: ```javascript let html = ""; html += "Benchmark Results
"; html += ""; if (metadata.skill_name) html += "" + escapeHtml(metadata.skill_name) + " — "; if (metadata.timestamp) html += metadata.timestamp + " — "; if (metadata.evals_run) html += "Evals: " + metadata.evals_run.join(", ") + " — "; html += (metadata.runs_per_configuration || "?") + " runs per configuration"; html += "
"; ``` ```javascript container.innerHTML = html; ``` ### Technical Analysis The review generator recursively reads files produced by evaluated skills and embeds their contents into an executable `- Remediation
View remediation
``` 3. Before embedding JSON into HTML, escape at least `<`, `>`, `&`, U+2028, and U+2029. Parse the element's text using `JSON.parse`. 4. Prefer serving the data from a local JSON endpoint with an explicit `application/json` content type. 5. Replace dynamically assembled HTML and `innerHTML` assignments with DOM construction and `textContent`. 6. Where HTML templates are unavoidable, apply contextual HTML escaping to every interpolated string, including timestamps, evaluation names, configuration values, deltas, notes, and evidence. 7. Add a restrictive Content Security Policy, such as a nonce-based `script-src`, and restrict `connect-src` to the loopback origin. 8. Add regression tests using output and benchmark values containing script-closing sequences, HTML tags, event handlers, quotes, and Unicode line separators. 9. Treat every evaluated output and benchmark file as untrusted, even when it was generated locally. ]]>
