Solved

PHP: cURL over HTTPS and CURLOPT_SSL_VERIFYPEER

Posted on 2014-09-20
15
522 Views
Last Modified: 2014-09-20
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
Comment
Question by:Scott Fell,  EE MVE
  • 5
  • 5
  • 3
  • +2
15 Comments
 
LVL 58

Accepted Solution

by:
Gary earned 500 total points
ID: 40334408
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
 
LVL 11

Expert Comment

by:Radek Baranowski
ID: 40334414
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
 
LVL 52

Author Comment

by:Scott Fell, EE MVE
ID: 40334458
The path to cert from site one?
0
 
LVL 11

Expert Comment

by:Radek Baranowski
ID: 40334464
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
 
LVL 11

Expert Comment

by:Radek Baranowski
ID: 40334466
*openssl
0
 
LVL 58

Expert Comment

by:Gary
ID: 40334468
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
 
LVL 58

Expert Comment

by:Gary
ID: 40334474
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
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 52

Author Comment

by:Scott Fell, EE MVE
ID: 40334477
I have real certs on both sites
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40334483
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
 
LVL 52

Author Comment

by:Scott Fell, EE MVE
ID: 40334494
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
 
LVL 58

Expert Comment

by:Gary
ID: 40334501
So just use the full path to the ssl/cert.pem file for the CAINFO path
0
 
LVL 58

Assisted Solution

by:Gary
Gary earned 500 total points
ID: 40334504
Not sure if you mean that is already on your server...grab them here.
http://curl.haxx.se/docs/caextract.html
0
 
LVL 52

Author Closing Comment

by:Scott Fell, EE MVE
ID: 40334552
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
 
LVL 34

Expert Comment

by:gr8gonzo
ID: 40334554
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
 
LVL 52

Author Comment

by:Scott Fell, EE MVE
ID: 40334574
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

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Introduction Many web sites contain image galleries; a common design for these galleries includes a page with a collection of thumbnail images.  You can click on each of the thumbnail images to see the larger version of the image.  This is easily i…
Both Easy and Powerful How easy is PHP? http://lmgtfy.com?q=how+easy+is+php (http://lmgtfy.com?q=how+easy+is+php)  Very easy.  It has been described as "a programming language even my grandmother can use." How powerful is PHP?  http://en.wikiped…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now