T09 · Insecure Skill Coding Practices
- Location
scripts/read_docx.py:195- Finding
Unhardened XML Parsing and Unbounded DOCX Archive Processing
- Content
View full analysis
list[dict[str, Any]]: try: data = zipf.read("word/comments.xml") except KeyError: return [] root = etree.fromstring(data) out = [] for c in root.findall(f".//{{{W_NS}}}comment"): out.append({ "id": _attr(c, "id"), "author": _attr(c, "author"), "date": _attr(c, "date"), "text": _text(c).strip(), }) return out def read_docx(path: str | Path) -> dict[str, Any]: """Read docx and return standard structure: { body, comments, path }. Body blocks have type, segments, blockIndex.""" path = Path(path) if not path.exists(): return {"error": f"File not found: {path}"} try: with zipfile.ZipFile(path, "r") as z: doc = z.read("word/document.xml") comments = _parse_comments(z) except Exception as e: return {"error": str(e)} root = etree.fromstring(doc) ``` `scripts/apply_edits_docx.py:410-419`: ```python with zipfile.ZipFile(docx_path, "r") as z_in: doc_bytes = z_in.read("word/document.xml") try: comments_bytes = z_in.read("word/comments.xml") comments_root = etree.fromstring(comments_bytes) except KeyError: comments_root = None comments_bytes = None doc_root = etree.fromstring(doc_bytes) ``` ### Technical Analysis DOCX files are ZIP archives containing XML resources. Both scripts treat the DOCX as potentially arbitrary input, load selected archive members entirely into memory with `ZipFile.read()`, and then parse those bytes through `etree.fromstring()` without explicitly ...[truncated 2389 chars]- Remediation
View remediation
