T09 · Insecure Skill Coding Practices
- Location
eval-viewer/generate_review.py:263- Finding
Stored Script Injection Through Unescaped Embedded Evaluation Data
- Content
View full analysis
str: """Generate the complete standalone HTML page with embedded data.""" template_path = Path(__file__).parent / "viewer.html" template = template_path.read_text() # Build previous_feedback and previous_outputs maps for the template previous_feedback: dict[str, str] = {} previous_outputs: dict[str, list[dict]] = {} if previous: for run_id, data in previous.items(): if data.get("feedback"): previous_feedback[run_id] = data["feedback"] if data.get("outputs"): previous_outputs[run_id] = data["outputs"] 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};") ``` The resulting data is inserted directly into this executable script element: ```html ` terminates the surround ...[truncated 2244 chars]- Remediation
View remediation
", "\\u003e") .replace("\u2028", "\\u2028") .replace("\u2029", "\\u2029") ) ``` 2. Prefer embedding the object in a non-executable JSON container: ```html ``` Then parse its text explicitly: ```javascript const EMBEDDED_DATA = JSON.parse( document.getElementById("embedded-data").textContent ); ``` 3. Apply a restrictive Content Security Policy. Avoid inline scripts or authorize only a fixed script hash or nonce. Restrict outbound connections with `connect-src 'self'` and other resource directives. 4. Treat every prompt, output file, filename, grading field, benchmark field, and feedback value as attacker-controlled input. 5. Add regression tests that generate and open viewers containing: - `` - HTML tags and event handlers - U+2028 and U+2029 characters - Strings containing `<`, `>`, and `&` 6. Consider rendering the review UI from a fixed application page and loading evaluation data through a JSON endpoint with the correct `application/json` content type, rather than injecting data into executable source code. ]]>
