T09 · Insecure Skill Coding Practices
- Location
templates/report-demo.html:797- Finding
DOM-Based Cross-Site Scripting Through Untrusted External Feed Data
- Content
View full analysis
Vulnerability Details
File Location:
templates/report-demo.html, lines 797–846 and 1071–1097
Vulnerability Type: DOM-based cross-site scripting (DOM XSS)
Risk Level: MediumComplete Code Snippet
javascript function mapItem(s,it){ return { c: s.comp||s.name, d:"自定义接入", pub: toISO(it.date), col: todayISO(), lv: s.lv, imp:"I2", review:(s.lv==="P2"||s.lv==="P3"), live:true, xval:false, ev: it.title, src: s.name, url: it.link||s.url||"#" }; } function fetchSource(s){ return new Promise((resolve,reject)=>{ if(!s.url){ resolve([]); return; } const ctrl = ("AbortController" in window)? new AbortController() : null; const timer = setTimeout(()=>{ if(ctrl) ctrl.abort(); reject(new Error("超时(8s)")); }, 8000); fetch(s.url, ctrl ? {signal:ctrl.signal, mode:"cors"} : {mode:"cors"}) .then(r=>{ if(!r.ok) throw new Error("HTTP "+r.status); return r.text(); }) .then(text=>{ clearTimeout(timer); let items=[]; if(s.type==="RSS"){ const doc=new DOMParser().parseFromString(text,"text/xml"); const nodes=doc.querySelectorAll("item, entry"); if(!nodes.length) throw new Error("RSS 无条目"); nodes.forEach(n=>{ const q=sel=>{ const e=n.querySelector(sel); return e?(e.textContent||e.getAttribute("href")||""):""; }; items.push({ title:q("title"), link:q("link")||q("id"), date:q("pubDate")||q("updated")||q("published") }); }); } else { let json; try{ json=JSON.parse(text); }catch(e){ throw new Error("非 JSON(RSS 请选 RSS 类型)"); } let arr = s.path ? getPath(json,s.path) : (Array.isArray(json)?json:(json.items||json.data||json.results)); if(!Array.isArray(arr)) throw new Error("未找到数组,检查列表路径"); items = arr.slice(0,20).map(o=>({ title:o.title||o.name||o.full_name||o.text||o.summary||String(JSON.stringify(o)).slice(0,60), link:o.html_url||o.url||o.link||o.homepage_url|| ...[truncated 3946 chars]- Remediation
View remediation
Remediation Suggestions
- Do not render external text through
innerHTML. Create elements with DOM APIs and assign all external strings throughtextContent. - If rich formatting is required, sanitize it with a maintained HTML sanitizer configured with a strict allowlist of necessary tags and attributes.
- Parse every external link with
new URL()and permit only explicitly supported schemes, normallyhttps:and optionallyhttp:. Rejectjavascript:,data:,file:, and malformed URLs. - Apply contextual escaping separately for HTML text, attribute values, and URLs. A single generic replacement function is not sufficient for every context.
- Treat competitor names, source names, titles, summaries, and all fetched URL fields as untrusted, including values returned by built-in GitHub and Hacker News queries.
- Add a restrictive Content Security Policy that disallows inline script and limits network destinations. This should be defense in depth rather than a substitute for encoding.
- Add regression tests covering HTML event handlers, SVG payloads, quote-breaking attribute payloads, malformed URLs, and
javascript:links.
- Do not render external text through
