T09 · Insecure Skill Coding Practices
- Location
references/dashboard-template.html:182- Finding
Stored Cross-Site Scripting in the Generated Memory Dashboard
- Content
View full analysis
// ===== DATA ===== const D = __DREAM_DATA_PLACEHOLDER__; ``` Memory-derived fields are subsequently inserted into the document through `innerHTML`: ```javascript D.insights.forEach(text => { const match = text.match(/^([\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}])\s*(.+)/u); const tag = match ? match[1] : '💡'; const body = match ? match[2] : text; list.innerHTML += ``; }); D.recentChanges.forEach(c => { list.innerHTML += `${tag} 洞察${body}`; }); D.suggestions.forEach(s => { list.innerHTML += `${icons[c.type]||'📝'}${c.id}${c.summary}${s}`; }); D.staleEntries.forEach(s => { list.innerHTML += ``; }); ``` The dashboard-refresh workflow explicitly inserts memory data into this template: ```markdown If memory/dashboard.html exists, regenerate it with latest data from MEMORY.md and dream-log.md. Use references/dashboard-template.html as the base, inject real data replacing __DREAM_DATA_PLACEHOLDER__. ``` ### Technical Analysis The dashboard treats memory-derived values as trusted HTML. Fields such as insights, suggestions, change summaries, and stale-entry summaries can originate from daily logs or imported memory bundles. They are interpolated into HTML strings and assigned through `innerHTML` without HTML escaping or sanitization. There are two associated injection surfac ...[truncated 2860 chars]${s.id}${s.summary}${s.daysSinceReferenced}天未提及- Remediation
View remediation
` block. Store data in a non-executable element: ```html ``` Serialize with a real JSON encoder and escape at least `<`, `>`, `&`, U+2028, and U+2029 before insertion. 2. Replace all `innerHTML` concatenation with DOM construction and `textContent`: ```javascript const item = document.createElement('div'); item.className = 'suggestion'; item.textContent = s; list.appendChild(item); ``` 3. Validate the complete dashboard data object against a strict schema. Require expected primitive types, bound string lengths, and allowlisted values for fields such as `type` and `layer`. 4. If limited formatting is necessary, process content through a maintained HTML sanitizer configured with a minimal allowlist. Do not allow scripts, event handlers, SVG, `style`, `iframe`, or unsafe URL schemes. 5. Add a restrictive Content Security Policy, preferably through an HTTP response header. For a standalone document, a meta policy is still preferable to having no policy: ```html ``` Move inline JavaScript to a separate trusted file so that `'unsafe-inline'` is not needed for `script-src`. 6. Treat daily logs and migration-bundle fields as untrusted throughout the complete collection, storage, report-generation, and dashboard-rendering pipeline. 7. Add security tests covering HTML tags, event attributes, SVG payloads, quotes, backticks, ``, Unicode separators, and malicious URL schemes. ]]>
