curl替代需要一个文件而不是allow_url_fopen?

时间:2011-03-18 21:53:30

标签: php security curl

我有一个PHP脚本,我试图从一个站点上的数据库中提取一些数据并将其显示在另一个站点上。我需要引用一些文件,但由于我的allow_url_fopen因安全原因设置为off,因此使用require filename.php会引发错误。是否有另一种方法来使用cURL“需要”文件?

示例OLD:

<?php require ('http://site.com/filename.php'); ?>

我试过这个,但它不起作用:

<?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;
?>

6 个答案:

答案 0 :(得分:2)

女士。拉姆齐,

2011年最广泛接受的问题解决方案是使用所谓的RESTful架构,这是几年前雅虎首次广泛支持的架构。它很容易,并且不会很复杂,你很快就会看到。

首先,在“服务器”端(您正在接收信息),您将创建一个简单的RESTful服务器,这是我能想到的最简单的服务器(在这里现场编码):

// 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";
}

现在,在您的客户端,您所要做的就是:

$ch = curl_init();
$params = json_encode(array('param1' => 'value', 'param2' => 'value'));
curl_setopt ($ch, CURLOPT_URL, 'http://site.com/restServer.php?action=foo&params=' . $params);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);

$data = json_decode($output);

它实际上非常好用。

我希望你选择我的答案!

答案 1 :(得分:0)

不要试图包含远程文件,这是一个巨大的安全风险 - 只需让远程文件生成您需要的数据并将其作为序列化/ json编码/ xml字符串(以最简单的方式)发送。

想想如果远程服务器受到攻击并且该文件被恶意代替的话会发生什么。您现在已经删除了恶意代码并在您的服务器上执行它。即使环境完全受到控制,远程代码加载也不是一个好主意。

答案 2 :(得分:0)

我担心这不起作用。通过curl获取php文件你没有得到php的源,但生成的输出。唯一可行的方法是以某种方式通过curl获取php文件的源代码(比如将php文件另存为.txt),但如果做得不对,那就是 HUUUGE 安全风险,所以我只是忘了它说实话!

答案 3 :(得分:0)

如果你只是试图显示远程生成的输出,那么你可以在你的卷曲电话后echo $contents;。只要您信任该来源为您的用户产生输出,那么这一点就相对无害了。

其他人对远程要求/包含的危险所说的是完全正确无误的,你不应该在任何情况下尝试,永远

答案 4 :(得分:0)

虽然我保证远程包含代码所涉及的风险,但有时无法避免。

因此,不要说“不,时期”,而是为共同利益更好地考虑这种可能性。

首先,您应该直接通过IP获取远程数据,而不是使用DNS。这会大大减少攻击面。

我可以给出的下一个建议就是你通过安全(SSL)连接读取它 - 它不会比那更好。知道您可以使用自己的证书。重要的是连接是加密的。

至于在本地执行代码,有几种方法可以做到这一点:

  • 使用eval:简单,但这是一个巨大的表演者。
  • 保存到文件并要求:我建议这个。但请确保使用随机文件名,以隐藏代码以防止窥探。或者只是将其保存在文档根目录之外。这是一个利用缓存机制的好机会。

<强>结论

https://123.145.168.190/file.txthttp://mydomain/file.txt更安全,即使安全证书是您自己的个人证书。虽然你可能想要在curl中禁用证书验证 - 很容易做到。

答案 5 :(得分:0)

如果两个站点都在您的控制之下,那么实际安全风险就会降低,而速度问题则更多。如果你说它是内容,那么我建议只是回应或<iframe>解决方案。

但无论如何,为了简单起见,尝试通过.htaccess php_flag allow_url_fopen 1启用url fopen包装器。
否则你的卷曲方法看起来不错。但是require不适用于字符串内容,而只适用于文件。你在尝试的本质上是:

eval($contents);

为了避免你可以使用的耻辱:

require(file_put_contents(tempnam("/tmp", "rem_"), $contents));