T09 · Insecure Skill Coding Practices
- Location
assets/report_template.html:234- Finding
Unescaped Dynamic Content Can Enable Script Injection in Generated Reports
- Content
View full analysis
AI时代职业规划报告 - {{USER_NAME}} ``` ```html{{CURRENT_ROLE}} {{INDUSTRY}} {{YEARS_EXP}}年经验 {{REPORT_DATE}}``` ```html {{TASK_ANALYSIS}} ``` ```html{{TIER1_RECOMMENDATIONS}}``` ```html{{WEEKLY_ACTION}}``` ```html ``` The corresponding generation instruction in `SKILL.md:252-273` states: ```text 2. Replace all `{{PLACEHOLDERS}}` with computed data: ``` It then maps user-derived and generated values directly to placeholders, including: ```text | `{{CURRENT_ROLE}}` | Q1 | Current job title | | `{{TASK_ANALYSIS}}` | Generated HTML | Task-level risk table | | `{{COMPETENCY_RADAR_DATA}}` | Phase 3 scores | JavaScript radar chart data | | `{{SCORE_CHART_JS}}` | Generated JS | Gauge chart initialization | ``` ### Technical Analysis The report-generation workflow instructs the agent to replace template placeholders directly, but it does not require contextual escaping, sanitization, schema validation, or safe DOM construction. The affected placeholders appear in several distinct parser contexts: - HTML text and title contexts, such as `CURRENT_ROLE` and `USER_NAME` - Raw HTML contexts, such as `TASK_ANALYSIS` and recommendation sections - JavaScript contexts, such as `SCORE_CHART_JS` and `COMPETENCY_RADAR_JS` A single generic replacement operation is unsafe across these contexts. For example, text containing HTML markup could terminate its surrounding element and inject a new element with an event ...[truncated 2024 chars]- Remediation
View remediation
`, `"`, and `'` for HTML text and attribute contexts. - Do not use one generic replacement function for HTML and JavaScript contexts. 2. Treat user-provided fields exclusively as text: - Insert them using `textContent` when constructing DOM elements. - Never concatenate profile fields or task descriptions into raw HTML. 3. Replace model-generated HTML fragments with structured data: - Have the model return validated JSON objects for tasks, recommendations, plans, and resources. - Render those objects through fixed, trusted templates. - If rich HTML is unavoidable, sanitize it with a strict allowlist that rejects scripts, event-handler attributes, dangerous URLs, iframes, and active embedded content. 4. Remove generated JavaScript placeholders: - Keep all chart initialization code static. - Pass only validated numeric arrays and fixed labels to that code. - Serialize data with a safe JSON encoder rather than manual string interpolation. - Escape `<` as `\u003c` when embedding serialized JSON inside an HTML script element. 5. Validate values against strict schemas: - Risk and competency scores must be finite numbers within their expected ranges. - CSS classes must come from fixed allowlists such as `low`, `medium`, `high`, and `critical`. - Dates and experience values must follow predefined formats. 6. Add a restrictive Content Security Policy. Prefer a design that permits only local, reviewed scripts and blocks inline event handlers and unexpected network destinations. 7. Add automated security tests using payloads that attempt to break out of: - HTML text nodes - Table cells - Element attributes - JavaScript strings - Script elements ]]>
