T09 · Insecure Skill Coding Practices
- Location
references/template_structure.md:335- Finding
Stored HTML and JavaScript Injection Through an Unvalidated Phrase Count
- Content
View full analysis
⚠️ ' + escHtml(w.t) + '' : ''; var phoneticHtml = w.p ? ' [' + escHtml(w.p) + ']' : ''; var meaningHtml = ''; var masteryField = w.v || w.i || 'normal'; // ... return '' + '' + '' + escHtml(w.w) + '' + escHtml(w.s) + '' + phoneticHtml + '' + '' + meaningHtml + '' + '' + '' + getMasteryLabel(masteryField) + '' + '考查 ...[truncated 3340 chars]- Remediation
View remediation
10000: raise ValueError("The count is outside the permitted range") return value ``` Use the validated value for both words and phrases: ```python count = validate_count(entry.get('c', 0)) ``` 2. **Encode every value placed into HTML.** Even after validation, apply output encoding as a defense-in-depth measure: ```javascript 'Exam count: ' + escHtml(String(maxC)) + '' ``` 3. **Prefer safe DOM APIs over HTML-string concatenation.** Create elements with `document.createElement()` and assign untrusted values through `textContent`. This prevents the browser from interpreting values as markup. 4. **Validate the complete input schema.** Enforce expected types and bounds for `w`, `s`, `m`, `c`, `l`, `v`, `i`, `p`, `e`, and `t`. Reject invalid records instead of silently applying defaults. 5. **Add regression tests.** Include phrase counts containing HTML tags, event handlers, strings, booleans, negative numbers, floating-point values, and excessively large integers. Verify that invalid records are rejected and that no input value can create executable DOM markup. 6. **Consider a restrictive Content Security Policy.** If the generated page is served over HTTP, use a policy that disallows inline event handlers and unauthorized network destinations. This is defense in depth and does not replace validation and safe rendering. ]]>
