19

I'm going to POST some data from site A to site B using PHP. Site A has a commercial SSL certificate. Site B is going to have a self-signed certificate. Is this doable? If not, are there any configuration options in PHP (or Apache) that I can set to bypass the restrictions?

Aaron
  • 10,386
  • 13
  • 37
  • 53

6 Answers6

41

Presumably you'll be using curl on server A? There's a couple options in curl to disable certificate validation, which'll allow self-signed certs through. The link will still be encrypted, but you won't be able to trust that server B really IS server B:

curlopt_ssl_verifypeer  (checking the CA auth chain)
curlopt_ssl_verifyhost  (hostname/certname match checks)

Example PHP code:

$ch = curl_init("https://example.com/example/path"); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
Swiss Mister
  • 3,260
  • 2
  • 20
  • 42
Marc B
  • 356,200
  • 43
  • 426
  • 500
  • 11
    Is there any way to configure PHP (or the client in general) to only accept a *specific* self-signed certificate? I'd imagine this would ostensibly be more secure than just not verifying the cert at all. – Doktor J Jun 30 '15 at 21:44
  • 2
    ATTENTION: This answer is very dangerous. Ignoring the certificate check is a very bad idea, it opens the door for man in the middle attacks! Ignoring certificate checks comes close to using plain http. Do not use this answer and read that one instead: https://stackoverflow.com/a/23585500/2650835 – JustRandom Dec 20 '18 at 20:38
  • 1
    @Dominik K Your reply does NOT address the OP's original question though. How he can make use of a SELF SIGNED certificate. Your solution only supports trusted 3rd party certificate authorities and consequently would not work in the OP's case. – Zack A Aug 01 '19 at 12:47
  • 1
    @ZackA I am talking about SELF SIGNED certifiates just for your info. It is just horrible wrong to disable certificate checks even with self signed certificates because this opens a huge attack vector for MITM attacks. Even with self signed certificates NEVER set the parameter CURLOPT_SSL_VERIFYPEER to false. An attacker could perform a MITM attack if you set this parameter to false. – JustRandom Aug 11 '19 at 12:13
  • `CURLOPT_SSL_VERIFYHOST` is not a `bool` but an `int` which takes values from 0 to 2. The correct way to disable host checking is to set the variable to zero. – 8ctopus Feb 02 '21 at 05:20
  • ***NO NO NO NO N̮̲̹͘O̸̥̯̙̪̝̬*** – i336_ May 19 '21 at 13:12
  • Disabling peer verification should only be done in the most preliminary stages of dev/test/integration. This should NEVER be used in production. This almost completely negates the security assurances provided by TLS/SSL. – chaserb Jul 13 '21 at 03:26
5

Answers suggesting to disable CURLOPT_SSL_VERIFYPEER should not be accepted. The question is "Why doesn't it work with cURL", and as correctly pointed out it is dangerous. Disabling certificate checks opens the door for man in the middle attacks, which comes close to using just plain text http.

The error is probably caused by not having an up-to-date bundle of CA root certificates. This is typically a text file with a bunch of cryptographic signatures that curl uses to verify a host’s SSL certificate.

You need to make sure that your installation of PHP has one of these files, and that it’s up to date (otherwise download one here: http://curl.haxx.se/docs/caextract.html).

Then set in php.ini:

curl.cainfo = <absolute_path_to> cacert.pem

If you are setting it at runtime, use:

curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");

Answer copied from https://stackoverflow.com/a/23585500/2650835 for security reasons.

JustRandom
  • 487
  • 1
  • 9
  • 19
  • 3
    Does NOT answer the OP's question which is how to get it to work with a SELF SIGNED certificate. Please re-read the OP's question and then post a solution applicable to his specific use case. – Zack A Aug 01 '19 at 12:50
  • 2
    @ZackA I am talking about SELF SIGNED certifiates just for your info. It is just horrible wrong to disable certificate checks even with self signed certificates because this opens a huge attack vector for MITM attacks. Even with self signed certificates NEVER set the parameter CURLOPT_SSL_VERIFYPEER to false. An attacker could perform a MITM attack if you set this parameter to false. – JustRandom Aug 11 '19 at 12:13
2

You can post to websites with self-signed certificates by adding the website's certificates to your list of trusted CAs. I've tested this in Debian, perhaps it also works in Ubuntu, CentOS, etc.

First get the self-signed website's certificate (ssws = self signed website):

openssl s_client -connect <ssws-hostname>:<ssws-port>

Ctrl-C out of the openssl command and examine the output. Locate the server's self-signed certificate which is encoded between these markers:

-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----

Copy the certificate, markers and all, and paste its contents into a new file, and give the file a ".crt" extension, such as "my-favorite-self-signed-website.crt". Then...

sudo chmod 644 my-favorite-self-signed-website.crt
sudo chown root:root my-favorite-self-signed-website.crt
sudo mv my-favorite-self-signed-website.crt /usr/local/share/ca-certificates/.
sudo /usr/sbin/update-ca-certificates

The last command should indicate "1 added", indicating your self signed website is now a bona fide trusted entity to this computer. PHP will automatically pick this up from the system and fall in line.

Unless you are doing some very preliminary development/testing/integration YOU SHOULD NEVER DISABLE PEER VERIFICATION IN SSL/TLS, as has been offered in other answers. Without peer verification, you might as well just do plain HTTP.

chaserb
  • 1,340
  • 1
  • 14
  • 25
1

It's doable. In PHP, if you are using cURL to perform the POST, you just need to set the options CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST to false so it doesn't fail because the certificate is self signed.

drew010
  • 68,777
  • 11
  • 134
  • 162
  • No, do not disable verification. Add exceptions instead. – i336_ May 19 '21 at 13:14
  • Disabling peer verification should only be done in the most preliminary stages of dev/test/integration. This should NEVER be used in production. This almost completely negates the security assurances provided by TLS/SSL. – chaserb Jul 13 '21 at 03:27
1

If you are asking the browser to POST the data, then the user will get the normal warnings about the certificate not being trusted.

If you're using cURL to perform the POST from within your PHP code, you'll want to disable cURL's SSL checks. According to a related question,

You'll need to set CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST to FALSE. This should disable the two main checks. They may not both be required, but this should at least get you going.

GargantuChet
  • 5,691
  • 1
  • 30
  • 41
  • For the sake of completeness, DO NOT DISABLE HTTPS VERIFICATION. ADD EXCEPTIONS INSTEAD. – i336_ May 19 '21 at 13:13
  • 1
    An explanation about *how* to add exceptions might serve the goal of completeness more thoroughly than this comment. – GargantuChet May 21 '21 at 07:03
  • Disabling peer verification should only be done in the most preliminary stages of dev/test/integration. This should NEVER be used in production. This almost completely negates the security assurances provided by TLS/SSL. – chaserb Jul 13 '21 at 03:28
0

In my case, only my development server is self-signed, so I set the verifypeer option to false and it works. But my production server is fully signed, so I do not set the verifypeer option. In either case, the verifyhost option is unnecessary.

David Spector
  • 1,520
  • 15
  • 21