55 lines
1.3 KiB
Plaintext
55 lines
1.3 KiB
Plaintext
== How to fix it in Core PHP
|
|
|
|
=== Code examples
|
|
|
|
The following code is vulnerable to deserialization attacks because it
|
|
deserializes HTTP data without validating it first.
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,php,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
$cookie = $_COOKIE['session'];
|
|
$session = unserialize($session); // Noncompliant
|
|
|
|
echo $session->auth ? "OK" : "KO";
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,php,diff-id=1,diff-type=compliant]
|
|
----
|
|
$cookie = $_COOKIE['session'];
|
|
list($session, $mac) = explode('|', $cookie, 2);
|
|
$hash = hash_hmac("sha256", $session, $KEY);
|
|
|
|
if (hash_equals($hash, $mac)) {
|
|
$session = unserialize($session);
|
|
} else {
|
|
die;
|
|
}
|
|
|
|
echo $session->auth ? "OK" : "KO";
|
|
----
|
|
|
|
=== How does this work?
|
|
|
|
include::../../common/fix/introduction.adoc[]
|
|
|
|
include::../../common/fix/safer-serialization.adoc[]
|
|
|
|
include::../../common/fix/integrity-check.adoc[]
|
|
|
|
Here, the compliant code example uses the `hash_hmac` function to compute the
|
|
integrity tag of the untrusted data. The underlying hash algorithm is set to
|
|
`sha256`, which is considered strong for this use case.
|
|
|
|
include::../../common/fix/pre-approved-list.adoc[]
|
|
|
|
=== Pitfalls
|
|
|
|
include::../../common/pitfalls/constant-time.adoc[]
|
|
|
|
The compliant code example uses the `hash_equals` function to compare
|
|
authentication tags. This one benefits from constant-time implementation.
|