T09 · Insecure Skill Coding Practices
- Location
scripts/generate_dashboard.py:127- Finding
Stored Script Injection Through Unescaped Dashboard Data
- Content
View full analysis
str: """Inject watchdog data and fix file:// compatibility.""" data_json = json.dumps(data, ensure_ascii=False, separators=(",", ":")) script_tag = f'' # crossorigin breaks file:// protocol (CORS), but type="module" is required for ES6 html = html.replace(' crossorigin', '') if "" in html: return html.replace("", f"{script_tag}\n", 1) return script_tag + "\n" + html ``` One source of externally controllable evidence is `scripts/scan_security.py:136-157`: ```python evidence = [] for label, regex in regex_rules: try: res = subprocess.run( ["git", "log", "-p", "--all", "--pickaxe-regex", f"-G{regex.pattern}", "--oneline", "--diff-filter=A"], cwd=target, capture_output=True, text=True, timeout=30 ) except Exception: continue if not res.stdout.strip(): continue added_lines = [ line[1:].strip() for line in res.stdout.splitlines() if line.startswith("+") and not line.startswith("+++") ] matched_lines = [line for line in added_lines if regex.search(line)] if matched_lines: hits.append(label) evidence.append(f"{label} 命中示例: {matched_lines[0][:160]}") ``` Another source is `scripts/scan_memory.py:315-327`: ```python evidence = [] for fpath, lines in matches.items(): evidence.append(f"{fpath}:") f ...[truncated 3385 chars]- Remediation
View remediation
str: return ( json.dumps(data, ensure_ascii=False, separators=(",", ":")) .replace("&", "\\u0026") .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("\u2028", "\\u2028") .replace("\u2029", "\\u2029") ) data_json = safe_json_for_html(data) data_tag = ( '' ) ``` The frontend should then read the value using `textContent`: ```javascript const element = document.getElementById("watchdog-data"); const data = JSON.parse(element.textContent); ``` 2. Apply context-appropriate escaping even when using `application/json`; an unescaped `` sequence can still terminate a script element at the HTML parser level. 3. Minimize evidence collection. Avoid preserving raw lines from Git history or memory when a count, file name, line number, or redacted excerpt is sufficient. 4. Redact credentials and token-like strings before they enter report files. The security scanner currently retains a matching line as evidence, which can itself expose the secret that the scanner detected. 5. Render all report-controlled frontend strings through React text nodes. Do not introduce `dangerouslySetInnerHTML` for titles, evidence, file paths, or remediation instructions. 6. Add regression tests using payloads including: ```text
