How to call "CURL" to call external URL - php

How to use "CURL" to call external URL since the url_fopen is disabled for security reasons. I want to open a pdf file. For security reason url_fopen function is disabled. So anyone can help me?
function Header()
{
$this->SetY(20);
$this->Image("images/logo-s.jpg", 120,0,80,20, "JPG", "www.example.com");
$this->Ln(4);
}

There are lots of answers for connecting, downloading or saving something to a URL by CURL function, but even if the CURL be disabled in your server you can still use stream_context_create, check this question
To do it with CURL try
$url = 'http://www.example.com/images/logo-s.jpg';
$path = '/path/to/images/logo-s.jpg';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
file_put_contents($path, $data); // to save it somewhere

First initialize a curl handler with:
$curl_handler = curl_init("http://www.linktomypdf.com/");
If you need to read it into a file:
$fp = fopen("mypdf.pdf", "w");
Now use curl_setopt() to set the option for curl_handler:
curl_setopt($curl_handler, CURLOPT_FILE, $fp);
First parameter is always curl_handler, second is which option you want to set , third is the value you want to set. So this call set CURLOPT_FILE to be $fp.
There are list of options you can find it here:
https://php.net/manual/en/function.curl-setopt.php
To make it easy to read the code:
$curl_handler = curl_init("http://www.linktomypdf.com/");
$fp = fopen("mypdf.pdf", "w");
curl_setopt($curl_handler, CURLOPT_FILE, $fp);
curl_exec($ch); //execute curl session
curl_close($ch); // close curl_handler
fclose($fp); // close file

Related

readfile vulnerability how to avoid

I heard that the function readfile is vulnerable as a php function, so I disabled it, and I have a script to download files, which uses this function:
$url = strip_tags($_GET['path']);
$fileName = strip_tags($_GET['file']);
header ("Content-type: octet/stream");
header ("Content-disposition: attachment; filename=".$fileName.";");
header ("Content-Length: ".filesize($url.$fileName));
readfile($url.$fileName);
exit;
If it is vulnerable, is there a way to avoid it or replace it with another function, I tried cURL, but the download failed, I got from this link
Using cURL:
<?php
set_time_limit(0);
$fp = fopen (dirname(__FILE__) . '/localfile.tmp', 'w+');//This is the file where we save the information
$ch = curl_init(str_replace(" ","%20",$url));//Here is the file we are downloading, replace spaces with %20
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp); // write curl response to file
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch); // get curl response
curl_close($ch);
fclose($fp);
?>
Thanks in advance
readfile isn't vulnerable per se. A possible attack vector is only given, when you pass un-sanitized data as parameter to it.
I mean $url. Your example doesn't show where URL comes from.
Let's use the worst case and assume $url comes from $_POST, e.g.
$url = $_POST['url']; and combine it with a nice Path Traversal attack (https://www.owasp.org/index.php/Path_Traversal).
You could limit the file access to the current dir (__DIR__).
Or use realpath() and exclude/restrict what readfile can do.
Referencing: How to avoid path traversal attacks
Ok, i've tested you cURL example. It works!
<?php
$url = 'http://www.thetimes.co.uk/tto/news/rss';
set_time_limit(0);
$fp = fopen (dirname(__FILE__) . '/localfile.tmp', 'w+');//This is the file where we save the information
$ch = curl_init(str_replace(" ","%20",$url));//Here is the file we are downloading, replace spaces with %20
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp); // write curl response to file
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch); // get curl response
curl_close($ch);
fclose($fp);
This downloads the content of the news/rss feed URL and saves it to localfile.tmp.

PHP copy() doesn't work for random URLS which redirect to files

trying to copy() .MP3 file from remote url but it always fails.
$link = str_replace(' ','%20','http://mp3hungama.com/music/download.php?song_id=80522');
if (!copy($link,'/home2/muser/tmp/newname.mp3')) {
echo 'copy failed !';
}
$link url redirects to http://mp3hungama.com/music/audio//Indian%20Movies/Indian%20Movies%20Hindi%20Mp3%20Songs/Singh%20Is%20Bling%20(2015)/songs/Cinema%20Dekhe%20Mamma%20#%20Mp3HunGama.Com.mp3
same code works for others random urls like www.example.com/download.php?id=2332. what's the specifically problem here or any other way to do this job ?
I've tested your code and I also couldn't download the file, then, I've used curl an it work as expected:
$local_file = "/home2/muser/tmp/newname.mp3";//This is the file where we save the information
$remote_file = "http://mp3hungama.com/music/download.php?song_id=80522"; //Here is the file we are downloading
$ch = curl_init();
$fp = fopen ($local_file, 'w+');
$ch = curl_init($remote_file);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_exec($ch);
curl_close($ch);
fclose($fp);
NOTE:
Make sure /home2/muser/tmp/ has write permissions.
TIP:
In the future, if you need to encode/decode a url, use urlencode or urldecode instead of str_replace
This link
already redirects to second link. So it's working already.

How will get content-size if I open remote file via HTTP using fopen

So.
$f = fopen('http_url_site_com_my_file_ext');
$info = stream_get_meta_data($f);
http://us1.php.net/manual/ru/function.stream-get-meta-data.php
as we read in docs, I can find content-lenth in
echo $info['wrapper-data'][#] ; // --> Content-length: 438;
also
echo $info['wrapper_type']; //--> http
In my case, I see
cURL instead http
and
$info['wrapper-data']['headers']; //empty array
So I cann't to get length of responce.
===========
info http://www.php.net/manual/en/reserved.variables.httpresponseheader.php
we can get the response headers such
$f = fopen('http_url_site_com_my_file_ext');
var_dump($http_response_header); // --> null.
$data = fread($f, 100);
var_dump($http_response_header); // --> array of all response headers.
But it is very very bad for my code. we open a lot of files at the start(if one of them is fault - die())
and then, we read from opened files.
============
QUESTION
1)if I will compile php without "--with-curlwrappers", why this experimental feature is present???
---php 5.4.21 (php-fpm)
---in phpinfo, I see no build option as '--with-curlwrappers'
2)
or how can I get response headers without reading stream
???
please, help me.
Is it mandatory to use fopen instead of cURL?
This example would work with cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $http_url_site_com_my_file_ext);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$r = curl_exec($ch);
print_r($r);
Also you can use http_head if HTTP extension is enabled.

Saving an image from a PHP URL using curl and PHP

I have tried to download an image from a PHP link. When I try the link in a browser it downloads the image. I enabled curl and I set “allow_url_fopen” to true. I’ve used the methods discussed here Saving image from PHP URL but it didn’t work. I've tried "file_get_contents" too, but it didn't work.
I made few changes, but still it doesn’t work. This is the code
$URL_path='http://…/index.php?r=Img/displaySavedImage&id=68';
$ch = curl_init ($URL_path);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$raw=curl_exec($ch);
curl_close ($ch);
$fp = fopen($path_tosave.'temp_ticket.jpg','wb');
fwrite($fp, $raw);
fclose($fp);
Do you have any idea to make it works? Please help. Thanks
<?php
if( ini_get('allow_url_fopen') ) {
//set the index url
$source = file_get_contents('http://…/index.php?r=Img/displaySavedImage&id=68');
$filestr = "temp_ticket.jpg";
$fp = fopen($filestr, 'wb');
if ($fp !== false) {
fwrite($fp, $source);
fclose($fp);
}
else {
// File could not be opened for writing
}
}
else {
// allow_url_fopen is disabled
// See here for more information:
// http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen
}
?>
This is what I used to save an image without an extension (dynamic image generated by server). Hope it works for you. Just make sure that the file path location is fully qualified and points to an image. As #ComFreek pointed out, you can use file_put_contents which is the equivalent to calling fopen(), fwrite() and fclose() successively to write data to a file. file_put_contents
You can use it as a function :
function getFile($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$tmp = curl_exec($ch);
curl_close($ch);
if ($tmp != false){
return $tmp;
}
}
And to call it :
$content = getFile(URL);
Or save its content to a file :
file_put_contents(PATH, getFile(URL));
You're missing a closing quote and semicolon on the first line:
$URL_path='http://…/index.php?r=Img/displaySavedImage&id=68';
Also, your URL is in $URL_path but you initialise cURL with $path_img which is undefined based on the code in the question.
Why use cURL when file_get_contents() does the job?
<?php
$img = 'http://…/index.php?r=Img/displaySavedImage&id=68';
$data = file_get_contents( $img );
file_put_contents( 'img.jpg', $data );
?>

How can get an image from a 301 redirect download link in PHP?

I'm trying to download this image with PHP to edit it with GD. I found many solutions for image links, but this one is a download link.
Edit:
$curl = curl_init("http://minecraft.net/skin/Notch.png");
$bin = curl_exec($curl);
curl_close($curl);
$img = #imagecreatefromstring($bin);
This is my current code. It displays "301 Moved Permanently". Are there CURLOPTs I have to set?
$curl = curl_init("http://minecraft.net/skin/Notch.png");
// Moved? Fear not, we'll chase it!
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
// Because you want the result as a string
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$bin = curl_exec($curl);
curl_close($curl);
$img = #imagecreatefromstring($bin);
Here is an option to directly save the image to a file (instead of using imagecreatefromstring):
<?php
$fileName = '/some/local/path/image.jpg';
$fileUrl = 'http://remote.server/download/link';
$ch = curl_init($fileUrl); // set the url to open and download
$fp = fopen($fileName, 'wb'); // open the local file pointer to save downloaded image
curl_setopt($ch, CURLOPT_FILE, $fp); // tell curl to save to the file pointer
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // tell curl to follow 30x redirects
curl_exec($ch); // fetch the image and save it with curl
curl_close($ch); // close curl
fclose($fp); // close the local file pointer
fopen - depends on your php settings if url fopen is allowed.
or curl
see the fine php manual.

Categories