I've noticed a little problem with CURL in PHP. Whenever I request a https:// connection it returns "false", and every website that I try to reach while I have my PHP page open reports to have an Untrusted certificate.
This is my request method:
private function request($url, $params, $method = "GET") {
if ($method == "GET")
$url = $this->structGET($url, $params);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if (isset($_SERVER['HTTP_USER_AGENT'])) {
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
} else {
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.X.Y.Z Safari/525.13.');
}
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$header[] = 'Accept-Language: EN';
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
if ($method == "POST") {
curl_setopt($ch, CURLOPT_POST, true);
if ($params)
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
}
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
And this is what Chrome returns when I try visiting Facebook.
The site's security certificate is not trusted!
You attempted to reach
www.facebook.com, but the server presented a certificate issued by an
entity that is not trusted by your computer's operating system. This
may mean that the server has generated its own security credentials,
which Google Chrome cannot rely on for identity information, or an
attacker may be trying to intercept your communications. You cannot
proceed because the website operator has requested heightened security
for this domain.
Don't use techniques that disable certificate verification. While they may "solve" your problem on the surface, they only ignore the problem, rather than fixing it. Never do this in production code.
The most likely cause is that you're on a network where there is a MITM corporate proxy. However legitimate these devices may be, they are effectively MITM devices.
What they do is that they will replace the original certificate with a certificate issued using their own internal CA, so as to be able to monitor the traffic.
If this device was legitimately set up by your network administrator, you should be able to get its CA certificate (in those circumstances, the CA certificate would typically be installed on all end-user machines centrally administered).
It's quite likely that, as a developer, you may have installed your own machine, and might not have the CA certificate installed. Ask your network administrator for that CA certificate, and install it with the certificates used by your browser and by curl within PHP (two different locations). Where the curl default location is may depend on the system you're using, but you can also configure it via CURLOPT_CAINFO.
Presumably, you're developing within a local network, but may possibly deploy that service on a different network when it's done. Make sure that this is configurable.
Yeah that happens when cURL tries to see if the SSL is verified. Facebook usually has a verified signature but may be because of network, it is returning invalid (happens in my case: using fortiguard proxy, facebook blocked!)
So, what you can do is, you can choose to ignore that error totally.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
That should fix it. But, if you want to fix it properly, then you should probably use a proxy or something or get a certificate for the server(if it is yours).
You need to add these two lines for SSL
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
Related
In the past couple of days, our PayPal IPN has stopped working and receiving a empty response from PayPal. Nothing has changed on the server or in our code.
Attempting to cUrl to the PayPal IPN url simply returns an empty response.
$url = "https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
$data = curl_exec($ch);
curl_close($ch);
print $data;
The above should return "INVALID" and works as expected on my localhost and from other servers.
Changing the url to any other domain other then PayPal also works without issues.
So it seems it only received the empty response from paypal.com
I wonder if any one has run into the issue or could give pointers where to look in the hope to- resolve it?
Kind Regards
Musaffar
It looks like Paypal made some security changes at the weekend. Some oscommerce users have been getting similar symptoms since Sunday with the curl error turning out to be:
SSL certificate problem: unable to get local issuer certificate
In their cases it was due to the local certificate copy only having the Paypal certificate and not the root or intermediate certificates, with the solution to update it.
The working certificate can be found in:
OSCOM Phoenix github
I would perhaps start checking if curl gave you any errors. PHP gives you in this case curl_errno($ch) and curl_error($ch) which will return a message or respectively the error code to it.
In case there is nothing suspicious to it. I would perhaps try to validate if you're able to run the above from your CLI on the server. (requires SSH access to it)
curl -H "User-Agent: ..." "https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate"
I hope this gives you a good starting point. Please let me know if this helps or if you need more ideas.
Edit#2: After comments where added from the author:
cUrl does indeed return an error : error 35 and the error message is as follows:
error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
In this case I would guess that your system is outdated and does not support the SSL ciphers from paypal. You could try to force a specific TLS version. As of today paypal webservers support only TLS1.2 or TLS1.3. This is how you can force it:
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
or
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_3);
Additionaly #Preston PHX mentioned in a comment a good refernces for this issue coming from paypal:
https://github.com/paypal/TLS-update#php
https://developer.paypal.com/docs/api/info-security-guidelines/
First at all, sorry for my bad English.
I'm trying to get the HTML code from https://www.uasd.edu.do/ but when I try to catch the code with the PHP function "file_get_contents()" or using cURL, it just simply doesn't work.
With "file_get_contents()" it returns with a 403 HTTP error. With cURL, it returns with a fictional captcha that just do not appear.
I tried sending Cookies with cURL, setting a user-agent, but I'm still on the same point. Also I tried to find the real IP address of the site, but with not success. Please help me! I'll really appreciate that.
The code:
$curl = curl_init();
if (!$curl) {
die("Is not working");
}
curl_setopt($curl, CURLOPT_URL, "https://uasd.edu.do/");
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0');
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_TIMEOUT, 50);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$html = curl_exec($curl);
echo $html;
curl_close($curl);
The output:
Please enable cookies. One more step Please complete the security
check to access www.uasd.edu.do Why do I have to complete a CAPTCHA?
Completing the CAPTCHA proves you are a human and gives you temporary
access to the web property. What can I do to prevent this in the
future?
If you are on a personal connection, like at home, you can run an
anti-virus scan on your device to make sure it is not infected with
malware.
If you are at an office or shared network, you can ask the network
administrator to run a scan across the network looking for
misconfigured or infected devices.
Cloudflare Ray ID: 4fcbf50d18679f88 • Your IP: ... •
Performance & security by Cloudflare
Note: The "please enable cookies" appear using and not using cookies.
I create a php-curl file to akses API from another server:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://192.168.4.2/sdk_service/rest/users/login/v1.1');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
// curl_setopt($ch, CURLOPT_CAINFO, "C:/xampp/htdocs/curl/cibinong/cacert.pem");
// curl_setopt($ch, CURLOPT_CAPATH, "C:/xampp/htdocs/curl/cibinong/");
$result = curl_exec($ch);
if (curl_error($ch)) {
echo curl_error($ch);
}
print_r($result);
I got error message:
SSL certificate problem: unable to get local issuer certificate
Help Me, maybe i miss something?
The problem is in the fact that you get an invalid SSL certificate, you need to turn off some checks. Can you try it with the following options?
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
This will skips the verification of the SSL host and SSL peer. Because, that is what you need in this case.
You're accessing a HTTPS URL using an IP address, which is very rarely actually working. Most sites require a name for SNI to be used to get the correct server cert and many CAs don't even sell you certs for plain IP addresses.
Instead of disabling the cert-check you should consider accessing this server using its "proper" and offical name so that the server knows which cert to offer in the TLS handshake.
If you really want to connect to this specific IP address and still use the right name in the URL, you can do so with the CURLOPT_RESOLVE option. Documented among the other CURL options.
Don't settle with disabling the cert-check. That's a poor work-around that only risks sticking around forever and makes you vulnerable.
As recommended by my DocuSign account manager, I am using Fiddler2 to capture the necessary trace for API certification. I am unable to retrieve the trace from the DocuSign domain and have narrowed it down to the fact that these are cURL calls.
According to Fiddler2, http://fiddler2.com/documentation/Configure-Fiddler/Tasks/ConfigurePHPcURL, the advice is to add the following to code:
curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');
where $ch = curl_init().
I've also tried
curl_setopt($curl, CURLOPT_PROXY, '127.0.0.1:8888');
Still no dice. I only get traffic from my application site. The following is all of my curl code:
$url = "https://demo.docusign.net/restapi/v2/login_information";
$curl = curl_init($url);
$ch = curl_init();
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("X-DocuSign-Authentication: $header"));
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_CAINFO, getcwd() ."/**the cert info");
curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');//allows fiddler to see requests
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
It's definitely talking to the DocuSign domain as my application is working, I'm just trying to get the trace. Any help is appreciated.
fiddler is client side program, it cannot see server traffic to other servers only traffic between client and server.
Unless your server is running locally (on the same computer that you are running fiddler) using 127.0.0.1 this will not work as 127.0.0.1 is the loopback ip for the computer, in this case the server would be trying to use itself as a proxy (which would be ok if the server computer itself was the one running fiddler). You need to change the ip to the computer running fiddler and make sure the server can access that port.
I was facing the exact same scenario, and I used a protocol analyzer such as Wireshark or TCPDUMP to see HTTP traffic at network level.
Of course the server needs to be running locally. Bellow you can find a screenshot example of traffic capture where you can clearly see the HTTP GET going out.
I am using php and google's new CSE in my website . The URL for request is like
https://www.googleapis.com/customsearch/v1?key=INSERT-YOUR-KEY&cx=017576662512468239146:omuauf_lfve&q=lectures
The connection is https and file_get_content() is getting failed. How can i get it working?
Since i need to host the site on some external web-hosting servers, I am in need of solution which don't alter php configuration file or work with default options found on most of web-hosting sites.
You can use curl:
## HTTPS url that you are targeting.
$url = "https://www.googleapis.com/customsearch/v1?key=INSERT-YOUR-KEY&cx=017576662512468239146:omuauf_lfve&q=lectures";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Opera/9.23 (Windows NT 5.1; U; en)');
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
## Below two option will enable the HTTPS option.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
$result = curl_exec($ch);
echo $result;
If you can't modify the config yourself, talk to the hosting provider. It most probably has to do with the lacking of openssl in the php core or startup.
If you are doing this for someone else and you have no control or contact with the host (the "some external host"), explain the situation and help them find a suitable host with the appropriate features enabled.