== How to fix it in Core PHP

=== Code examples

The following noncompliant code is vulnerable to XPath injection because untrusted data is concatenated to an XPath query without prior validation.

==== Noncompliant code example

[source,php,diff-id=1,diff-type=noncompliant]
----

function authenticate(DOMXpath $xpath, string $username, string $password): bool { 
    $expression = "/users/user[@name='" . $username . "' and @pass='" . $password . "']";
    $entries = $xpath->evaluate($expression);

    return $entries.length > 0
}

----

==== Compliant solution

[source,php,diff-id=1,diff-type=compliant]
----

function authenticate(DOMXpath $xpath, string $username, string $password): bool {
    if (!preg_match("/^[a-zA-Z0-9]*$/", $username) || !preg_match("/^[a-zA-Z0-9]*$/", $password)) {
        return false;
    }

    $expression = "/users/user[@name='" . $username . "' and @pass='" . $password . "']";
    $entries = $xpath->evaluate($expression);

    return $entries->length > 0
}

----

=== How does this work?

As a rule of thumb, the best approach to protect against injections is to systematically ensure that untrusted data cannot break out of the initially intended logic.

include::../../common/fix/validation.adoc[]

In the compliant solution, a regex match ensures the username and password only contain alphanumeric characters before executing the XPath query.
