Skip to content

fix: quote XPath string literals via _xpath_safe helper#615

Merged
btorresgil merged 1 commit into
developfrom
fix/xpath-safe-helper
May 14, 2026
Merged

fix: quote XPath string literals via _xpath_safe helper#615
btorresgil merged 1 commit into
developfrom
fix/xpath-safe-helper

Conversation

@btorresgil
Copy link
Copy Markdown
Member

Summary

  • Adds a private _xpath_safe() helper in panos.base that wraps a value as an XPath 1.0 string literal, picking the appropriate quote character (and falling back to concat() for values containing both quote types).
  • Routes every interpolated value (vsys names, object UIDs, serials, registered IPs, etc.) through the helper so a stray quote in user input can no longer alter predicate structure or scope.
  • Touches panos/base.py, panos/firewall.py, panos/network.py, panos/panorama.py, panos/predefined.py, and panos/userid.py. The ENTRY and MEMBER constants drop their literal '…' wrapping; the helper supplies it.
  • For inputs without quote characters, generated XPath strings are byte-for-byte identical to the previous output, so existing tests that assert exact xpath values remain valid.

Test plan

  • pytest tests/ — full existing suite passes
  • Verified backward compatibility: tests/test_vsys_xpaths.py, tests/test_device_profile_xpaths.py, tests/test_base.py, tests/test_versioning.py, and tests/test_predefined.py all green
  • New regression tests added locally for the helper, the SUFFIX consumer, _root_xpath_vsys, delete_similar, and _TEMPLATE_VSYS_XPATH substitution

Add a private _xpath_safe() helper in panos.base that wraps a value as a
valid XPath 1.0 string literal: single quotes by default, double quotes
when the value contains a single quote, and concat() when it contains
both. Use it everywhere the SDK interpolates a value into an XPath
predicate.

Templates that previously embedded the surrounding quotes (e.g.
"[@name='%s']") drop them; the helper now supplies the correct quoting.
For inputs without quote characters the rendered XPath is byte-identical
to the previous output, so existing tests asserting exact xpath strings
remain green.

Touched sites:
  - panos/base.py: ENTRY/MEMBER constants, _root_xpath_vsys, SUFFIX
    consumer, delete_similar joiner, vsys-dict import delete,
    _TEMPLATE_VSYS_XPATH, both _get_param_specific_info overloads,
    VersionedPanObject.XPATH, delete_import, and the three re.sub
    'entry varname' sites
  - panos/firewall.py, panos/panorama.py, panos/userid.py,
    panos/network.py, panos/predefined.py: all variable interpolations
    into [@name=...], [@ip=...], and text()=... predicates

Hardcoded literals such as entry[@name='localhost.localdomain' are
unchanged.
@YuvalFradkin1
Copy link
Copy Markdown

Subject: Follow-up: CWE-643 XPath Injection in pan-os-python — PR #615

Hi,

I’m following up on my report regarding a CWE-643 XPath Injection issue in pan-os-python (notably around panos/base.py lines 52 and 415).

I noticed PR #615 (“fix: quote XPath string literals via _xpath_safe helper”), which appears to address the same class of vulnerability by introducing a centralized quoting mechanism for XPath values.

Could you please confirm whether my report has been associated with this fix for triage and bounty evaluation? If helpful, I can provide additional details or validation.

Thank you for your time and for the prompt remediation work.

Best regards,
Yuval Fradkin

@btorresgil btorresgil merged commit a3cb530 into develop May 14, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants