T09 · Insecure Skill Coding Practices
- Location
scripts/kml_tool.py:46- Finding
Unbounded KMZ Decompression and XML Parsing Allow Resource Exhaustion
- Content
View full analysis
ParsedDocument: path = Path(path_text) suffix = path.suffix.lower() if suffix == ".kmz": with zipfile.ZipFile(path) as archive: names = [name for name in archive.namelist() if name.lower().endswith(".kml")] if not names: raise ValueError("KMZ archive does not contain a .kml file.") preferred = "doc.kml" main_name = preferred if preferred in names else names[0] data = archive.read(main_name) try: root = ET.fromstring(data) except ET.ParseError as exc: raise ValueError(f"Invalid XML inside KMZ: {exc}") from exc return ParsedDocument(source_type="kmz", root=root, origin=main_name) if suffix != ".kml": raise ValueError("Input file must end with .kml or .kmz.") try: root = ET.parse(path).getroot() ``` ### Technical Analysis The KMZ processing path selects a KML archive member and decompresses its entire contents into memory with `archive.read(main_name)`. It does not inspect or enforce limits on: - The member's declared uncompressed size. - The compression ratio between `ZipInfo.compress_size` and `ZipInfo.file_size`. - The number of archive entries. - The total decompressed archive size. - The amount of data read into memory. - The number or depth of XML elements. - The number of coordinate tuples subsequently collected into lists. After decompression, `ET.fromstring(data)` constructs an in-memory XML tree. Subsequent processing creates additional lists of XML elements and coordinates, increasing the memory required for a large payload. The plain KML path has a related issue because `ET.parse(path).get ...[truncated 2151 chars]- Remediation
View remediation
