PHP cURL provides SSL-Error AFTER sending the data? - php

This is my Code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postValues);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
Now the $result is "false" and the curl_error() shows me the SSL-Error "Peer's Certificate issuer is not recognized.".
But although there is this error, the post data has been sent to the $apiUrl.
Is this correct? Bug or feature? ;)
How can I improve this to prevent sending data to an insecure service?
Thanks in advance! :)

There is two solution for this...
Solution - 1
If you want to skip check SSL certificate use....
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
Solution - 2
If you have certificate with you use....
curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");
Thanks.

Finally I found the reason why the data has been transfered although there has been a curl error!
There was a redirect to another location and with "followlocation" active, the error happened on the redirected site!
So the data has been sent to the $apiUrl and has been processed. After this the curl call has been redirected and the error appeared.
My trust in logic has been restored :D

This is incorrect; cURL does not send any data when there is a problem with the SSL certificate.
(I just tested with a connection to a local script - the second script did not run when the first script encountered an SSL error while connecting to it.)

Related

Why is my curl request showing a different result than the browser?

My php Curl request(also curl command in terminal) unfortunately shows a different code than opening the URL manually in the browser.
Here is my problem: I want to display the currently available films from https://reservierung.kinolambach.at/filmlist/?location_id=1 (german cinema)
on my website. When you check your network tab, the website sends an ajax call to a url with the specific date to the server and gets a response. Try it out by calling https://reservierung.kinolambach.at/filmlist/?location_id=1&date=4.1.2021&film_table=true in your browser(due to Covid there is a test film available on 4. Jan 2021)
My website does not run on the same domain.
Using an ajax call did not work because of CORS-Policy, so my second approach is to load the data via curl from php.
Here is my php code, which does not work. For every request I make I get the result "No film available on this day". It seems as if "No film available on this day" (german: 'Für diesen Tag ist kein Programm verfügbar.') is the "default" response.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://reservierung.kinolambach.at/filmlist/?location_id=1&date=4.1.2021&film_table=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPGET, 1);
curl_setopt($ch, CURLOPT_COOKIESESSION, 0);
$result = curl_exec($ch);
echo($result);
curl_close($ch);
There are several curl_setopt which I tried out, none did work.
Here is my question
How is it possible, that curl shows a different result than calling the url in the browser? You can even try it in your terminal with curl https://reservierung.kinolambach.at/filmlist/?location_id=1&date=1.1.2021&film_table=true
How can I change this? I guess it has to do with the header.
Thanks in advance and all the best!
curl_setopt($ch, CURLOPT_URL, 'https://reservierung.kinolambach.at/filmlist/?
location_id=1&date=4.1.2021&film_table=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'C:/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, 'C:/tmp/cookies.txt');
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
Works form me with cookies enabled. On second request as my comment before.

setup cURL for SSL

Once again, another question concerning cURL and SSL, as I cannot find matching answers to my problem.
I have working SSL on my webserver, with trusted cert and green signs on browsers address bar a.s.o., NOT self signed. So good, so far.
Now I want communicate with cURL and use the following function (POST data not added yet):
function ssltest(){
$post_data = '';
$url = 'https://myserver/test.php';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_MUTE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
//curl_setopt($ch, CURLOPT_CAINFO, 'sslstuff/cacert.pem');
curl_setopt($ch, CURLOPT_CAINFO, 'sslstuff/false.pem');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
echo ssltest();
As the cacert.pem I use this one, which I found in my browser, which is obviously identical to what I found here http://curl.haxx.se/ca/cacert.pem
In the code shown above there is a false.pem to be seen. Now what ? If this file is empty, there's no response from Server, but I tested to paste the cert from another enterprise from the list on curl.haxx.se I get the same correct answer from the server as result, as when I use my correct .pem
What's the issue ? What I am missing ?
"there's no response from Server"
I think that's very unlikely. I suspect there is no HTTP response from the server, but that the SSL negotiation is failing - but you've got no error checking in your code. If $output===false, have a look at curl_error().
You might want to play around with VERIFYHOST and VERIFYPEER to pin down the exact cause of the problem.

PHP curl error: ssl peer certificate or ssh remote key was not ok

I am having some issues communicating to certain third party system, through CURL in PHP.
This is part of the code I have to submit come requests
$query = '<tag>some xml content with request data</tag>';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://secure.certainsystem.com/function.php");
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
curl_setopt($ch, CURLOPT_POST, 1);
$data = curl_exec($ch);
The request is the same for all cases, but sometimes I don't get any data from the curl_exec($ch), and instead, when I run curl_error($ch), I get:
SSL peer certificate or SSH remote key was not OK
This is not happening all the times, but it is happening, so I'm not sure what the problem could be, if the problem is in the code, or there is a problem in the third party system I'm comunicating to.
I searched for this message error in other places and here as well, and I found that if CURLOPT_SSL_VERIFYPEER is set to true, then it could be a problem with the third party system's certificate, perhaps a self-signed one. But in my case, that option is set to 0, which I assume is taken as false.
Recently I found there is an option CURLOPT_SSL_VERIFYHOST, but I'm not setting that option to any value, so I think it is taking the default, which according to PHP.net documentation, is 2, which means:
2 to check the existence of a common name and also verify that it matches the hostname provided.
Thank you very much for your help.
add options
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
more see here https://answers.launchpad.net/ubuntu/+question/171188
Although I am answering an old post, I think it will help the new viewers-
You can check the problem by adding
curl_setopt($ch, CURLOPT_VERBOSE, 1);
The reason is explained in my post here.

Delicious API Authentication

I got delicious account a few days ago, and I want to use its API with PHP/curl. I use such a function:
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.delicious.com/v1/posts/add?&url=SOME_URL");
curl_setopt($ch, CURLOPT_USERAGENT, $USER_AGENT);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $CONNECT_TIMEOUT);
curl_setopt($ch, CURLOPT_TIMEOUT, $CONNECT_TIMEOUT);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_USERPWD, "MY_USER:MY_PASS");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$result=curl_exec($ch);
curl_close($ch);
return $result;
It always returns ACCESS DENIED error. I know the code works because I use the same code with Bing API and it works perfectly (also tested with some other sites that use http authorization - works perfectly).
So what is wrong here? My user/pass is OK, since the same URL works if I enter it into browser and type my user/password.
In case someone has the same problem, here's the answer. I contacted Delicious team, and the problem was related to their SSL. Here's what they sent to me:
"This is likely the result of our SSL certificate expiring accidentally. We're working to resolve this issue as soon as possible and get the certificate for https://delicious.com renewed. The secure website, as well as the API, should be working again within a few hours"

php cURL and Instagram Photos

So someone Tweets a link to a photo on Instagram : http://instagr.am/p/QSVkR8LS3H/
This redirects from http://t.co/bOJ4EX2j to http://instagr.am/p/QSVkR8LS3H/ to the actual Instagram page http://instagram.com/p/QSVkR8LS3H/ where the photo resides.
Cool. All that is good and well. Now I want a cURL to follow the tweeted link and download that final page, that contains the < img > of the photo. Script looks basically like this :
$target = 'http://t.co/bOJ4EX2j';
$ch = curl_init();
curl_setopt ($ch, CURLOPT_HTTPGET, TRUE);
curl_setopt ($ch, CURLOPT_POST, FALSE);
curl_setopt ($ch, CURLOPT_COOKIEJAR, COOKIE_FILE); // Defined Constant
curl_setopt ($ch, CURLOPT_COOKIEFILE, COOKIE_FILE);
curl_setopt ($ch, CURLOPT_TIMEOUT, CURL_TIMEOUT); // Defined Constant
curl_setopt ($ch, CURLOPT_USERAGENT, WEBBOT_NAME); // Defined Constant
curl_setopt ($ch, CURLOPT_URL, $target); // Target site
curl_setopt ($ch, CURLOPT_REFERER, ''); // Referer value
curl_setopt ($ch, CURLOPT_VERBOSE, FALSE); // Minimize logs
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // No certificate
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, TRUE); // Follow redirects
curl_setopt ($ch, CURLOPT_MAXREDIRS, 4); // Limit redirections to four
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE); // Return in string
# Create return array
$return_array['FILE'] = curl_exec($ch);
$return_array['STATUS'] = curl_getinfo($ch);
$return_array['ERROR'] = curl_error($ch);
# Close PHP/CURL handle
curl_close($ch);
return $return_array;
Now this script has many more components but that's the just of the cURL part. Now, it does manage to spit back that it landed on the correct final page http://instagram.com/p/QSVkR8LS3H/) where the image is - but this is what the $return_array['FILE'] spits out :
500 Server Error
An internal server error occurred.
Even when if you navigate to the page in your browser, with cookie's off, and not signed into Instagram (if you were) the page loads completely!
What the hell am I missing that's not allowing this to cURL script to download the Instagram page?! It works on just about every other page I try it! Just not Instagram.com?!
Please someone help me crack this nut of a issue - I'd greatly appreciate any help or insight anyone might have.
If you're running this code on a server and not your local machine, it's possible that there's some misconfigured proxy between the server and Instagram.com. Check the code from your local machine, making sure it also works in a browser on the same machine.
If you get this working and discover, as Justin Wood has said, that you have an HTML page and not the image you wanted, I can help you with some PHP to get the image URL (for which you'd then have to run another cURL request).
As said by many of us, that code seems to work perfectly fine. All i can suggest is that you make sure error reporting is on and then check your PHP error logs in your base directory.
You might also want to check that the cURL module is enabled in PHP.ini.
Not sure what else could be wrong.

Categories