diff --git a/.semgrepignore b/.semgrepignore index c83cb8df..a9ec84d2 100644 --- a/.semgrepignore +++ b/.semgrepignore @@ -19,3 +19,13 @@ uv.lock .gitleaks-baseline.json .bandit-baseline.json .semgrepignore + +# draw.io fixer scripts — defusedxml does the actual parsing, but each +# script also borrows Element / ElementTree / indent from xml.etree for +# type hints and pretty-printing. The `import xml` Semgrep pattern fires +# on the borrow regardless of how it's written, and inline `# nosemgrep` +# is not honored in GHAS mode. Suppress at the file level. +plugins/deploy-on-aws/scripts/lib/fix_icon_colors.py +plugins/deploy-on-aws/scripts/lib/fix_nesting.py +plugins/deploy-on-aws/scripts/lib/fix_step_badges.py +plugins/deploy-on-aws/scripts/lib/post_process_drawio.py diff --git a/plugins/deploy-on-aws/scripts/lib/fix_icon_colors.py b/plugins/deploy-on-aws/scripts/lib/fix_icon_colors.py index 913776b3..cf609564 100644 --- a/plugins/deploy-on-aws/scripts/lib/fix_icon_colors.py +++ b/plugins/deploy-on-aws/scripts/lib/fix_icon_colors.py @@ -10,6 +10,19 @@ import argparse import defusedxml.ElementTree as ET +# defusedxml.ElementTree re-exports the secure parsing helpers (parse, +# fromstring) but NOT the Element / ElementTree type aliases, nor the +# indent() pretty-printer (Python 3.9+). We borrow those names from the +# stdlib while keeping defusedxml's parse() as the actual XML entry +# point — defusedxml is what protects against XXE / billion-laughs. +# Filed as awslabs/agent-plugins#154 (Element / ElementTree) and #167 +# (indent). Inline-suppressed because Semgrep matches the inner AST +# nodes of a multi-line `from ... import (...)`, so a directive on the +# preceding line does not propagate to lines 2-N of the block. +from xml.etree.ElementTree import Element as _Element, ElementTree as _ElementTree, indent as _indent # nosec B405 # nosemgrep +ET.Element = _Element # type: ignore[attr-defined] +ET.ElementTree = _ElementTree # type: ignore[attr-defined] +ET.indent = _indent # type: ignore[attr-defined] # Broken shape names → correct shape names SHAPE_RENAMES: dict[str, str] = { diff --git a/plugins/deploy-on-aws/scripts/lib/fix_nesting.py b/plugins/deploy-on-aws/scripts/lib/fix_nesting.py index 9080e68e..ea5f4076 100644 --- a/plugins/deploy-on-aws/scripts/lib/fix_nesting.py +++ b/plugins/deploy-on-aws/scripts/lib/fix_nesting.py @@ -17,6 +17,19 @@ import argparse import defusedxml.ElementTree as ET +# defusedxml.ElementTree re-exports the secure parsing helpers (parse, +# fromstring) but NOT the Element / ElementTree type aliases, nor the +# indent() pretty-printer (Python 3.9+). We borrow those names from the +# stdlib while keeping defusedxml's parse() as the actual XML entry +# point — defusedxml is what protects against XXE / billion-laughs. +# Filed as awslabs/agent-plugins#154 (Element / ElementTree) and #167 +# (indent). Inline-suppressed because Semgrep matches the inner AST +# nodes of a multi-line `from ... import (...)`, so a directive on the +# preceding line does not propagate to lines 2-N of the block. +from xml.etree.ElementTree import Element as _Element, ElementTree as _ElementTree, indent as _indent # nosec B405 # nosemgrep +ET.Element = _Element # type: ignore[attr-defined] +ET.ElementTree = _ElementTree # type: ignore[attr-defined] +ET.indent = _indent # type: ignore[attr-defined] def get_style_dict(style_str: str) -> dict[str, str]: diff --git a/plugins/deploy-on-aws/scripts/lib/fix_step_badges.py b/plugins/deploy-on-aws/scripts/lib/fix_step_badges.py index 0599a74d..51d83a29 100644 --- a/plugins/deploy-on-aws/scripts/lib/fix_step_badges.py +++ b/plugins/deploy-on-aws/scripts/lib/fix_step_badges.py @@ -21,6 +21,19 @@ import math import re import defusedxml.ElementTree as ET +# defusedxml.ElementTree re-exports the secure parsing helpers (parse, +# fromstring) but NOT the Element / ElementTree type aliases, nor the +# indent() pretty-printer (Python 3.9+). We borrow those names from the +# stdlib while keeping defusedxml's parse() as the actual XML entry +# point — defusedxml is what protects against XXE / billion-laughs. +# Filed as awslabs/agent-plugins#154 (Element / ElementTree) and #167 +# (indent). Inline-suppressed because Semgrep matches the inner AST +# nodes of a multi-line `from ... import (...)`, so a directive on the +# preceding line does not propagate to lines 2-N of the block. +from xml.etree.ElementTree import Element as _Element, ElementTree as _ElementTree, indent as _indent # nosec B405 # nosemgrep +ET.Element = _Element # type: ignore[attr-defined] +ET.ElementTree = _ElementTree # type: ignore[attr-defined] +ET.indent = _indent # type: ignore[attr-defined] from dataclasses import dataclass diff --git a/plugins/deploy-on-aws/scripts/lib/post_process_drawio.py b/plugins/deploy-on-aws/scripts/lib/post_process_drawio.py index 3142ee2e..1944cfbc 100644 --- a/plugins/deploy-on-aws/scripts/lib/post_process_drawio.py +++ b/plugins/deploy-on-aws/scripts/lib/post_process_drawio.py @@ -16,6 +16,19 @@ import os import sys import defusedxml.ElementTree as ET +# defusedxml.ElementTree re-exports the secure parsing helpers (parse, +# fromstring) but NOT the Element / ElementTree type aliases, nor the +# indent() pretty-printer (Python 3.9+). We borrow those names from the +# stdlib while keeping defusedxml's parse() as the actual XML entry +# point — defusedxml is what protects against XXE / billion-laughs. +# Filed as awslabs/agent-plugins#154 (Element / ElementTree) and #167 +# (indent). Inline-suppressed because Semgrep matches the inner AST +# nodes of a multi-line `from ... import (...)`, so a directive on the +# preceding line does not propagate to lines 2-N of the block. +from xml.etree.ElementTree import Element as _Element, ElementTree as _ElementTree, indent as _indent # nosec B405 # nosemgrep +ET.Element = _Element # type: ignore[attr-defined] +ET.ElementTree = _ElementTree # type: ignore[attr-defined] +ET.indent = _indent # type: ignore[attr-defined] from pathlib import Path MAX_FILE_SIZE = 2 * 1024 * 1024 # 2 MB