Blind Exploitation
When results are not rendered, use boolean conditions that flip the app's response to leak bits (like blind SQLi). You need any observable difference: success vs error text, status code, or measurable processing time.
Core Boolean Pattern
Assume input lands in a predicate on username:
/users/user[username='<INPUT>']Inject a universally true clause:
invalid' or '1'='1If the app reports "success" for the injected value, you confirmed XPath injection (blind).
Name Length, Name, and Children Count
Use XPath functions in boolean checks:
Length of root element name:
invalid' or string-length(name(/*[1]))=L and '1'='1Character-by-character name of a node:
invalid' or substring(name(/*[1]),POS,1)='a' and '1'='1Number of children:
invalid' or count(/users/*)=N and '1'='1Iterate L, POS, N until the response flips to "success".
Enumerating Schema
Start at
/*[1].Determine name and
count(/*).Recurse into each child
/*[i].
Automating (Python template)
Time-based Signal (when responses are identical)
XPath has no sleep(), but you can force heavy evaluation to create measurable delay when a condition is true:
If the substring condition is true,
count((//.)[count(//.)])triggers exponential traversal and slows the response.If false, that branch is skipped (short-circuit), response remains fast.
Increase nested count() stacks for small documents, but beware of DoS on large ones.
Practical Tips
Stabilize the positive/negative signal (match exact success text, status code, or timing threshold).
URL-encode payloads when needed; prefer POST to avoid length limits.
Narrow
string.printableto speed up (e.g.,ascii_letters + digits + '{}_:-@./').Cache intermediary findings (lengths, partial names) to resume interrupted runs.
Redact secrets/flags from notes; store sensitive outputs separately.
Last updated