T09 · Insecure Skill Coding Practices
- Location
scripts/generate_quiz.py:500- Finding
Arbitrary JavaScript Execution Through Unsafe Quiz Data Embedding
- Content
View full analysis
const quizData = {json.dumps(data, ensure_ascii=False)}; let answered = {{}}; ``` Additional unescaped HTML and attribute sinks include: ```python ``` ```python``` ```python html_parts.append(f'{i+1}') ``` ```python html += f'{t} ×{count}' html += f'{b} ×{count}' html += f'{kp} ×{count}' ``` ```python sections_html += f'' ``` ### Technical Analysis The renderer accepts quiz data from a command-line argument or standard input and writes it into a standalone HTML document. Although some visible text fields use `html.escape()`, the complete data object is serialized directly inside an executable `` sequence. A field containing a value such as: ```html ``` can terminate the original script element and introduce a new executable script. Other fields, including question IDs, types, difficulty labels, Bloom labels, and knowledge-point labels, are interpolated into HTML ...[truncated 2210 chars]{qtype}
共{len(group)}题,{group_score}分- Remediation
View remediation
... ``` Before embedding, encode at least `<`, `>`, `&`, U+2028, and U+2029. For example: ```python serialized = json.dumps(data, ensure_ascii=False) serialized = ( serialized .replace("&", "\\u0026") .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("\u2028", "\\u2028") .replace("\u2029", "\\u2029") ) ``` Then parse the element's text content: ```javascript const quizData = JSON.parse( document.getElementById('quiz-data').textContent ); ``` 3. Remove inline handlers such as `onchange="checkAnswer(...)"`. Bind events with `addEventListener()` from static JavaScript. 4. Validate question IDs with a strict allowlist, such as `^[A-Za-z0-9_-]{1,64}$`. 5. Restrict question type, difficulty, and Bloom level to known enumerated values. 6. Apply context-specific encoding: - HTML text encoding for text nodes. - HTML attribute encoding for attribute values. - Safe DOM APIs for element construction. - JavaScript serialization only for JavaScript values. 7. Prefer constructing dynamic elements with `document.createElement()`, `textContent`, and `setAttribute()` rather than concatenating HTML strings. 8. Add regression tests using payloads containing quotes, angle brackets, ``, inline-event syntax, and malformed identifiers. 9. Consider a restrictive Content Security Policy that disallows inline scripts and limits network destinations as a defense-in-depth control. ]]>
