PHP Curl SSL Zertifikat Problem

PHP Curl SSL Zertifikat Problem

Viele PHP Entwickler kennen die SSL Problematik mit CURL: certificate verify failed.

Als Lösung sehen viele den dirty Fix:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Das löst das Problem zwar, verursacht aber eine Sicherheitslücke die Man-In-The-Middle (MitM) Attacken ermöglicht.

Die saubere Lösung hierfür ist:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // Überprüft ob der "Common name" existiert

und mit dem Hostnamen des Servers übereinstimmt.

curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/CA.crt"); // Hier entsprechend das CA Cert. im PEM Format hinterlegen

Wer das ganze noch ausbauen möchte:

$url = 'https://patrick-othmer.de';
$ch = curl_init($url);
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);

/**
* Sollte ein SSL Fehler auftreten, versuchen wir es erneut mit dem CA Zertifikat.
* Fehler 77 bezeichnet CURLE_SSL_CACERT_BADFILE welche nicht als Konstante in den
* PHP Manuals definiert ist.
*
* Danke an http://phpsecurity.readthedocs.org/en/latest/Transport-Layer-Security-(HTTPS-SSL-and-TLS).html
*/
$error = curl_errno($ch);
if ($error == CURLE_SSL_PEER_CERTIFICATE || $error == CURLE_SSL_CACERT
|| $error == 77) {
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/cert-bundle.crt');
$result = curl_exec($ch);
}

Somit ist man zumindest gegen „einfache“ Man-In-The-Middle (MitM) Attacken geschützt.