T09 · Insecure Skill Coding Practices
- Location
scripts/plan_generator.py:65- Finding
Stored HTML and Script Injection in Generated Reports
- Content
View full analysis
= 0.8 else ("prob-mid" if prob >= 0.5 else "prob-low") risk_icon = {"冲": "🚀", "稳": "✅", "保": "🛡️"}.get(risk, "") hist_text = str(hist_ranks[-1]) if hist_ranks else "-" rows.append(f""" {rank} {uni} {group} {majs} {hist_text} {prob_text} {risk_icon} {risk} {note} """) ``` Profile fields are also inserted without HTML escaping: ```python report = report.replace("{{TITLE}}", f"2026年高考志愿填报方案") report = report.replace( "{{SUBTITLE}}", f"{province_name} | {subject} | {score}分 | 位次{rank}" ) report = report.replace("{{GENERATED_TIME}}", now) ``` Warnings are converted into HTML list items without escaping: ```python warnings_html = "" if warnings: for w in warnings: warnings_html += f'- {w}
\n' else: warnings_html = '- 未检测到明显风险,请结合个人情况复核
' report = report.replace("{{WARNINGS}}", warnings_html) ``` ### Technical Analysis `plan_generator.py` treats profile data, admissions records, major names, notes, risk values, and warning messages as trusted HTML. These values ...[truncated 2730 chars]- Remediation
View remediation
str: return escape(str(value), quote=True) ``` Apply this function to all profile, admissions, plan, and warning fields before inserting them into the template: ```python uni = html_text(item.get("university_name", "-")) group = html_text(item.get("major_group_name", "-")) majs = html_text(", ".join(map(str, item.get("majors_in_group", []))) or "-") note = html_text(item.get("note", "")) ``` 2. Do not insert untrusted values into attribute names or class attributes. Map `risk_level` to a fixed allowlist: ```python allowed_risks = {"冲", "稳", "保"} risk = item.get("risk_level", "") if risk not in allowed_risks: risk = "-" ``` 3. Escape profile and warning values independently: ```python subtitle = " | ".join([ html_text(province_name), html_text(subject), html_text(score), html_text(rank), ]) warnings_html = "\n".join( f"- {html_text(w)}
" for w in warnings ) ``` 4. Introduce strict JSON-schema validation before report generation. Enforce expected field types, maximum lengths, numeric ranges, and enumerated values. 5. Prefer a template engine with automatic HTML escaping enabled rather than manual string replacement. 6. Add a restrictive Content Security Policy to the generated document, adjusted to the report's actual requirements: ```html ``` 7. Add regression tests containing payloads in every externally controlled field. Verify that characters such as `<`, `>`, `"`, `'`, and `&` appear encoded in the resulting HTML and cannot create new elements or attributes. ]]>
