T09 · Insecure Skill Coding Practices
- Location
generator.py:277- Finding
Stored HTML and Script Injection in Generated Resumes
- Content
View full analysis
') else: html_lines.append('') elif in_code_block: html_lines.append(line) elif line.startswith('# '): html_lines.append(f'{line[2:]}
') elif line.startswith('## '): html_lines.append(f'{line[3:]}
') elif line.startswith('### '): html_lines.append(f'{line[4:]}
') elif line.startswith('- '): html_lines.append(f'- {line[2:]}
') elif line.startswith('>'): html_lines.append(f'{line[1:].strip()}
') elif line.strip(): html_lines.append(f'{line}
') else: html_lines.append('
') ``` ### Technical Analysis Resume data supplied through JSON or command-line arguments is first converted to Markdown and then inserted directly into HTML elements. The converter does not HTML-escape text before placing it inside headings, paragraphs, list items, blockquotes, or code blocks. Consequently, HTML in fields such as the applicant name, self-introduction, employer, project description, or skills is interpreted as active markup rather than plain text. For example, a field containing an image element with an `onerror` handler can introduce JavaScript into the generated document. The same issue also affects the document title construction at `generator.py:259`, where the applicant name is concatenated directly into the `` element. ### Attack Path 1. An attacker prepares resume JSON containing an HTML payload in a supported field, for example: ```json { "name": "<img src=x onerro ...[truncated 1113 chars]- Remediation
View remediation
`, event-handler attributes, closing-tag breakouts, and malformed HTML. A safe basic conversion should follow this pattern: ```python from html import escape safe_text = escape(line[2:], quote=True) html_lines.append(f'{safe_text}
') ``` ]]>
