Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1041
  • Last Modified:

PHP: cURL over HTTPS and CURLOPT_SSL_VERIFYPEER

I have a couple of sites that I control.   I need to post data from site one to site two.   I don't need a response from site two, just post a couple of variables and stay on site one.   If I use https, I found I can use CURLOPT_SSL_VERIFYPEER set to false to allow the https connection.  

I assume this should be safe since I control both sites.  What needs to be added to use CURLOPT_SSL_VERIFYPEER set to true/default?
 
$url = 'https://my_other_site.com/test.php';
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);

 curl_setopt($ch, CURLOPT_POSTFIELDS,
          http_build_query(
              array(
                  'var1' => urlencode('abc123'),
                  'var2 => urlencode('xyz456')
              )
          )
 );

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$response = curl_exec ($ch);


if($response) 
{
	echo  $response;
}
else
{
	echo curl_error($ch);
}
    
curl_close ($ch);

Open in new window

0
Scott Fell,  EE MVE
Asked:
Scott Fell,  EE MVE
  • 5
  • 5
  • 3
  • +2
2 Solutions
 
GaryCommented:
Set it to to true
Also need if the path is different from the curl default.
curl_setopt ($ch, CURLOPT_CAINFO, "/pathto/cacert.pem");

If you don't have an up to date ca cert bundle then get it from
http://curl.haxx.se/

p.s.
curl doesn't come with a CA bundle by default anymore, so it's likely you don't have them.
0
 
Radek BaranowskiFull-stack Java DeveloperCommented:
In other words you need to obtain public key of site two certificate and place it on a trust store on site one for it to be able to verify if ssl connection from site two uses known and valid certificate.
0
 
Scott Fell, EE MVEDeveloper & EE ModeratorAuthor Commented:
The path to cert from site one?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Radek BaranowskiFull-stack Java DeveloperCommented:
If site one had ssl up and running the best way to obtain is public key is to open its https port in browser,save the certificate and add it to trust store on site two. You might need to use opensll tools to convert it to pem format of That's what curl needs.
0
 
Radek BaranowskiFull-stack Java DeveloperCommented:
*openssl
0
 
GaryCommented:
No the path to the certs on site one - it needs to be able to negotiate what site 2 is sending.
Since curl doesn't come with any CA certs then it doesn't negotiate a verifiable secure connection (verify peer set to false will accept any ssl certificate).
0
 
GaryCommented:
Does site 2 have a real ssl cert and not a self generated one? If it's self generated then you may as well just use false, as true would never work anyway
0
 
Scott Fell, EE MVEDeveloper & EE ModeratorAuthor Commented:
I have real certs on both sites
0
 
Ray PaseurCommented:
You can use cURL POST for this and you can also use fSockOpen() to make a post-method request.  A safe design for this handshake process, used by PayPal, goes something like this:

1. Site A prepares the post data and saves the post arguments in the database
2. Site A makes a post to Site B.
3. Site B makes a post back to Site A with "cmd=>verify" in the first request element, with the other request elements appended in order so that Site A can verify the data.
4. Site A looks up the post arguments in the database and if they match, makes a post back to Site B with the word "verified" and if they don't match, responds with "wrong."

If you already have the HTTPS connection, why would you be concerned about using the certificates?
0
 
Scott Fell, EE MVEDeveloper & EE ModeratorAuthor Commented:
I looked at my authorize.net sdk.  They have a file named cert.pem and the code that access it is
 if ($this->VERIFY_PEER) {
            curl_setopt($curl_request, CURLOPT_CAINFO, dirname(dirname(__FILE__)) . '/ssl/cert.pem');
        } else {
			if ($this->_log_file) {
				file_put_contents($this->_log_file, "----Request----\nInvalid SSL option\n", FILE_APPEND);
			}
			return false;
        }

Open in new window


Would I just make a pem file of one of my certificates?
0
 
GaryCommented:
So just use the full path to the ssl/cert.pem file for the CAINFO path
0
 
GaryCommented:
Not sure if you mean that is already on your server...grab them here.
http://curl.haxx.se/docs/caextract.html
0
 
Scott Fell, EE MVEDeveloper & EE ModeratorAuthor Commented:
That worked.    I downloaded http://curl.haxx.se/ca/cacert.pem and saved to my server and then used CURLOPT_CAINFO as below (windows) and worked.  

curl_setopt ($ch, CURLOPT_CAINFO, '\inetpub\vhosts\MySite\httpdocs\folder\cacert.pem');
0
 
gr8gonzoConsultantCommented:
Sounds like you're already getting help with the "how" but allow me to respond to: "I assume this should be safe since I control both sites. "

That is a bad assumption. By verifying the remote certificate, you are helping avoid man-in-the-middle attacks. Basically, a malicious user can blast some specially-crafted network packets to your servers, telling your servers that they should route traffic through a different gateway. At this point, the malicious user could route traffic INTENDED for your "Site B" to his/her own server and grab the data. Of course, it's useless to them to grab encrypted data, so part of that process is to use THEIR own SSL certificate instead, so that your "Site A" is encrypting data using the malicious user's SSL public certificate (which identifies itself as "Site B"). Now, when the malicious user's server gets traffic that goes to Site B, it can decrypt the traffic and get to the real data. Optionally, it can then pass on the original request to Site B and return Site B's response back to Site A. This way, it SEEMS like everything is working fine. However, you'll have no idea that there is a server in-between Site A and Site B that is capturing all the original data and responses.

So when you tell cURL to verify the certificate of Site B, it is checking the entire certificate chain (the certificate itself and also the certificates that issued it) to make sure you're actually dealing with the Site B certificate and not some other 3rd party certificate that you're not expecting. And unless the malicious user has access to Site B's private key, they cannot use Site B's certificate to disguise themselves.

Hopefully all of that makes sense and explains why you should always verify peer certificates (even if both sites are 100% trustworthy). :)
0
 
Scott Fell, EE MVEDeveloper & EE ModeratorAuthor Commented:
Thanks gr8gonzo, great point.  I just read that and that's why I didn't stick with setting CURLOPT_SSL_VERIFYPEER to false.  

Below is what I ended up with where cacert.pem is from http://curl.haxx.se/ca/cacert.pem 

$url = 'https://my_other_site.com/test.php';
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);

 curl_setopt($ch, CURLOPT_POSTFIELDS,
          http_build_query(
              array(
                  'var1' => urlencode('abc123'),
                  'var2 => urlencode('xyz456')
              )
          )
 );

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // changed to true
curl_setopt ($ch, CURLOPT_CAINFO, '\inetpub\vhosts\MySite\httpdocs\folder\cacert.pem');  //added

$response = curl_exec ($ch);


if($response) 
{
	echo  $response;
}
else
{
	echo curl_error($ch);
}
    
curl_close ($ch);

Open in new window

0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 5
  • 5
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now