From a3e53900330e6a0ca27fbc910ecfb28dae073e33 Mon Sep 17 00:00:00 2001
From: David Sanchez <64162682+dsfaccini@users.noreply.github.com>
Date: Sun, 30 Aug 2026 22:20:08 -0500
Subject: [PATCH] fix: reject POM entity declarations
---
graphify/manifest_ingest.py | 5 +++++
tests/test_manifest_ingest.py | 11 ++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/graphify/manifest_ingest.py b/graphify/manifest_ingest.py
index 717d9ad9a4..424e72ff16 100644
--- a/graphify/manifest_ingest.py
+++ b/graphify/manifest_ingest.py
@@ -269,6 +269,11 @@ def _parse_gomod(text: str) -> dict | None:
def _parse_pom(text: str) -> dict | None:
+ # ElementTree does not cap entity expansion, so reject declarations before
+ # parsing rather than allowing a crafted POM to consume excessive memory.
+ lowered = text.lower()
+ if "\n'
' com.acme\n widget\n 2.0\n'
@@ -75,6 +75,15 @@ def test_pom_parses_artifact_and_deps(tmp_path):
assert any(e["target"] == "pkg_org_lib_core" for e in r["edges"])
+def test_pom_with_internal_entity_is_rejected_before_parsing(tmp_path):
+ p = _write(tmp_path / "pom.xml",
+ ']>\n'
+ '&artifact;\n')
+ r = extract_package_manifest(p)
+ assert r["nodes"] == [] and r["edges"] == []
+ assert r["error"] == "manifest parse error: refusing XML with DOCTYPE/ENTITY declaration"
+
+
# ── #1377: a package referenced by N manifests is ONE node ───────────────────
def test_apm_dependency_collapses_to_single_canonical_node(tmp_path):