T09 · Insecure Skill Coding Practices
- Location
assets/template.html:1087- Finding
Persistent DOM-Based Cross-Site Scripting Through Unsanitized Question Data
- Content
View full analysis
${type}`; return `${r.label}`; } ``` ```javascript state.questions.forEach((q, idx) => { const card = document.createElement('div'); card.className = 'question-card'; card.id = `qcard-${q.id}`; card.innerHTML = `第 ${idx+1} 题 ${badgeHtml(q.type)}${q.question}
-
${q.options.map((opt,i) => {
const key = ['A','B','C','D','E'][i];
return `
- ${key} ${opt.slice(3)} `; }).join('')}
`; ``` Question data stored in `localStorage` is subsequently rendered again without sanitization: ```javascript list.innerHTML = `📖 解析${q.explanation}
- Remediation
View remediation
{ selectOption(q.id, key); }); ``` 3. **Sanitize any intentionally supported rich HTML.** If explanations must contain formatting, process them with a maintained sanitizer configured with a restrictive element and attribute allowlist. Event-handler attributes, scripts, embedded frames, dangerous URLs, and active SVG content should be prohibited. 4. **Validate question data before use.** Enforce a schema in the generation script and, defensively, in the browser. At minimum: - Restrict IDs to a conservative character set and maximum length. - Restrict answers to supported option letters. - Require `questions` and `options` to be arrays with bounded sizes. - Require expected fields to be strings with reasonable length limits. - Reject duplicate identifiers. - Restrict question types and categories to known values where practical. 5. **Treat localStorage records as untrusted.** Validate and safely render every field loaded from localStorage. Existing malicious or malformed records must not be assumed safe merely because they were written by the application. 6. **Deploy a restrictive Content Security Policy.** After removing inline event handlers and inline script dependencies, use a policy similar to: ```http Content-Security-Policy: default-src 'self'; s ...[truncated 386 chars]
