T09 · Insecure Skill Coding Practices
- Location
scripts/parse-resume.py:65- Finding
Spreadsheet Formula Injection Through Attacker-Controlled Resume Fields
- Content
View full analysis
dict: phone = PHONE_RE.search(text) email = EMAIL_RE.search(text) lines = [l.strip() for l in text.splitlines() if l.strip()] name = lines[0] if lines else "" return { "name": name, "phone": phone.group() if phone else "", "email": email.group() if email else "", "gender": "未知", "age": None, "city": "", } ``` ```python def _export_tabular(results: list, output: str, fmt: str): rows = [] for r in results: b = r.get("basic", {}) rows.append({ "姓名": b.get("name", ""), "手机": b.get("phone", ""), "邮箱": b.get("email", ""), "工作年限": r.get("work_years", ""), "最高学历": r.get("highest_degree", ""), "技能标签": ", ".join(r.get("skills", {}).get("tech", [])), "质量分": r.get("quality_score", ""), "解析时间": r.get("parse_time", ""), "来源文件": r.get("source_file", ""), }) try: import pandas as pd df = pd.DataFrame(rows) if fmt == "csv": df.to_csv(output, index=False, encoding="utf-8-sig") else: df.to_excel(output, index=False) except ImportError: sys.exit("缺少依赖: pip install pandas openpyxl") ``` ### Technical Analysis Resume contents are untrusted input. `extract_basic()` takes the first non-empty line of a resume and stores it directly as the candidate name. `_export_tabular()` subsequently passes this value to pandas without neutralizing spreadsheet control characters. A name beginning with `=`, `+`, `-`, or `@` may be interpreted as a formula when the generated CSV or Excel file is opened in spreadsheet software. Leading whitespace, tab, carriage-return, or newlin ...[truncated 1957 chars]- Remediation
View remediation
