← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

XPath Injection

Security CWE-643 OWASP A3:2021 CVSS 7.5 PHP 5.0+ Intermediate
debt(d5/e5/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep and psalm — both specialist SAST/static-analysis tools — as the detection mechanism. The code_pattern (interpolated user data in DOMXPath::query) is not caught by default linting but is reachable by targeted SAST rules, placing this squarely at d5.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix notes that PHP's DOMXPath does not natively support parameterised queries, so there is no simple one-call swap. Every XPath expression using user input must be audited and manually escaped or restructured, which typically touches multiple query sites across files. The common_mistakes confirm the lack of a native parameterised alternative makes this more than a single-line fix, pushing to e5.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The applies_to scope is web and API contexts — not universal across all PHP work. The burden is real but confined: only code paths that build XPath queries from user input carry the risk. The rest of the codebase is unaffected, making this a localised tax rather than a system-wide structural weight.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field directly captures the trap: developers assume XPath injection is rare or that familiar SQL-injection defenses (parameterised queries) transfer over, but PHP's DOMXPath has no native parameterisation standard. This contradicts SQL, where parameterised queries are universally available and the idiomatic fix. A competent developer familiar with SQL injection mitigations will guess wrong about the remediation path here, justifying t7.

About DEBT scoring →

Also Known As

XPath injection XML path injection

TL;DR

Unsanitised input manipulates XPath queries against XML documents, enabling data extraction or authentication bypass.

Explanation

XPath injection is analogous to SQL injection but targets XPath 1.0/2.0 queries over XML data stores. Injecting ' or '1'='1 can bypass authentication or extract all nodes from an XML document. Unlike SQL, XPath 1.0 has no parameterised query support — the only reliable defence is strict input validation (allowlisting expected characters) and avoiding dynamic XPath construction with user input. PHP's DOMXPath::evaluate() is vulnerable when user input is concatenated into the query string.

How It's Exploited

username = ' or '1'='1
# XPath: //user[name/text()='' or '1'='1' and ...]
# Returns all users — authentication bypass

Common Misconception

XPath injection is rare because few applications use XPath. Any application using XML-based configuration, SAML authentication, or document stores queried with XPath is potentially vulnerable — and unlike SQL, XPath has no parameterised query standard in most languages.

Why It Matters

XPath injection against XML data stores mirrors SQL injection — an attacker can extract the entire document structure or bypass authentication with a carefully crafted input.

Common Mistakes

  • Concatenating user input directly into XPath expressions: //users/user[name='{$input}'].
  • Not using parameterised XPath — PHP's DOMXPath does not natively support parameters, requiring manual escaping.
  • Underestimating the impact because XML stores seem less common — SOAP services and config files are frequent targets.
  • Using single quotes to delimit XPath strings then accepting single quotes in user input.

Avoid When

  • Never concatenate user input directly into an XPath expression string.
  • Do not assume XML data is safe because it came from your own database — second-order injection applies.

When To Use

  • Use parameterised XPath queries or whitelist-validate user input before embedding in any XPath expression.
  • Treat XPath expressions with user input the same way as SQL — never concatenate.

Code Examples

✗ Vulnerable
// User input in XPath — analogous to SQL injection
$q = "//user[name/text()='$username' and password/text()='$password']";
// username = ' or '1'='1  → returns all users
✓ Fixed
// Strict input validation — XPath has no native parameterisation in PHP
if (!preg_match('/^[a-zA-Z0-9@._-]+\$/', $username)) abort(400);

// Escape both quote types for safe embedding:
function xpathString(string $v): string {
    if (!str_contains($v, "'")) return "'$v'";
    if (!str_contains($v, '"')) return '"'.$v.'"';
    $parts = explode("'", $v);
    return "concat('" . implode("', \"'\", '", $parts) . "')"; 
}
$q = '//user[name/text()=' . xpathString($username) . ']';

Added 15 Mar 2026
Edited 31 Mar 2026
Views 81
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 1 ping W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 2 pings S 1 ping M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Amazonbot 7 ChatGPT 7 Ahrefs 6 Bing 5 PetalBot 5 Perplexity 3 Unknown AI 3 Google 3 SEMrush 3 Scrapy 2 Brave Search 2 Applebot 2 Meta AI 1 Twitter/X 1
crawler 44 crawler_json 5 pre-tracking 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Use parameterised XPath queries or escape user input with addslashes() for XPath — single quotes in user-supplied values can break XPath expressions just like SQL injection
📦 Applies To
PHP 5.0+ web api
🔗 Prerequisites
🔍 Detection Hints
XPath query with user input: "//user[name='$username']"; no escaping of user values in XPath expressions; DOMXPath::query with interpolated user data
Auto-detectable: ✓ Yes semgrep psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✗ Manual fix Fix: Medium Context: Function Tests: Update
CWE-643


✓ schema.org compliant