curl alternative to require a file instead of allow_url_fopen?
I have a php script that I'm trying to pull some data from a database on one site and display it on another site. I need to reference some files, but using require filename.php throws errors due to my allow_url_fopen being set to off for security reasons. Is there an alternative way to "require" the file using cURL instead?
Example OLD:
<?php require ('http://site.com/filename.php'); ?>
I tried this, but it doesn开发者_Go百科't work:
<?php
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, 'http://site.com/filename.php');
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$contents = curl_exec($ch);
curl_close($ch);
// display file
require $file_contents;
?>
Ms. Ramsey,
The most widely accepted solution for your problems in 2011 is to use what's called a RESTful architecture, which was first widely championed by Yahoo a few years back. It's REALLLLLLLY easy and not complicated at all as you will soon see.
First, on the "server" side (where you're receiving the information) you create a simple RESTful server, the most simplistic one I can think of being (coding on the spot here):
// RESTful service
$action = 'action_' . filter_input(INPUT_GET, 'action', FILTER_SANITIZE_STRING);
$params = filter_input(INPUT_GET, 'params', FILTER_SANITIZE_STRING);
if (function_exists($action))
{
// Run the action w/ the parameters
$data = call_user_func_array($action, json_decode($params));
// Encode the data in a HTTP friendly way...
$output = json_encode($data);
echo $output;
}
else
{
trigger_error('Invalid action: ' . htmlspecialchars($action), E_USER_ERROR);
}
function action_foo($param1)
{
return "Param 1: $param1";
}
Now, on your client side, all you have to do is this:
$ch = curl_init();
$params = json_encode(array('param1' => 'value', 'param2' => 'value'));
curl_setopt ($ch, CURLOPT_URL, 'http://site.com/restServer.php?action=foo¶ms=' . $params);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$data = json_decode($output);
It actually works pretty nicely.
I hope you pick my answer!
Instead of trying to include the remote file, which is a huge security risk - simply have that remote file generate the data you need and send it over as a serialized/json encoded/xml string (whichever's easiest).
Think of what happens if the remote server is compromised and that file is replaced with something malicious. You've now sucked down hostile code and are executing it on your server. Remote code loading is never a good idea, even if the environment is completely controlled.
I'm afraid that won't work. By getting the php file through curl you aren't getting the source of the php but the generated output. The only way this will work is by somehow fetching the source of the php file with curl (like saving the php file as .txt) but that is a HUUUGE security risk if not done right so i would just forget about it to be honest!
If you're only trying to display the output produced remotely, then you can just echo $contents;
after your curl call. That alone is relatively harmless, as long as you trust that source to produce output for your users.
What the others have said about the dangers of remote require/include is completely true and correct, and you should not be attempting that under any circumstances whatsoever, ever.
Although I vouch for the risk involved in including code remotely, it sometimes can't be avoided.
So instead of saying "no, period.", it would be better for the common good to actually consider the possibility.
First of, you should get the remote data through an IP directly, instead of using DNS. This would decrease the attack surface considerably.
The next advise I can give as that you read this through a secure (SSL) connection - it can't get much better than that. Know that you can use your own certificates. What's important is that the connection is encrypted.
As to executing the code locally, there are a couple of ways to do this:
- Using
eval
: Easy, but it's a huge performance eater. - Saving to a file and requiring it: I'd suggest this one. Make sure you use a random filename though, in order to hide code from prying eyes. Or simply save it outside of document root. This is a great chance to make use of a caching mechanism.
Conclusion
https://123.145.168.190/file.txt
is way safer than http://mydomain/file.txt
even if the security cert is your own personal one. Though you may want to disable certificate validation in curl - easy to do.
If both sites were under your control, it would be less of a practical security risk and more of a speed issue. If you say it is content, then I'd advise for just echoing or an <iframe>
solution.
But anyway, try to enable the url fopen wrappers via .htaccess php_flag allow_url_fopen 1
for simplicity.
Otherwise your curl approach looks ok. However the require
does not work on string content, but only on files. What you are attempting is in essence:
eval($contents);
To avoid the stigma you could use:
require(file_put_contents(tempnam("/tmp", "rem_"), $contents));
精彩评论