curl альтернатива требовать файл вместо allow_url_fopen? - PullRequest
3 голосов
/ 19 марта 2011

У меня есть скрипт php, который я пытаюсь извлечь из базы данных на одном сайте и вывести их на другой сайт. Мне нужно сослаться на некоторые файлы, но при использовании require filename.php выдает ошибки из-за того, что мой allow_url_fopen отключен по соображениям безопасности. Есть ли альтернативный способ «потребовать» файл, используя вместо этого 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 ]

2 голосов
/ 19 марта 2011

Ms. Рэмси,

Наиболее широко принятым решением ваших проблем в 2011 году является использование так называемой архитектуры RESTful, которая впервые была широко распространена Yahoo несколько лет назад. Это действительно просто и совсем не сложно, как вы скоро увидите.

Во-первых, на стороне «сервера» (где вы получаете информацию) вы создаете простой сервер 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);

На самом деле это работает довольно хорошо.

Надеюсь, вы выберете мой ответ!

0 голосов
/ 19 марта 2011

Если бы оба сайта находились под вашим контролем, это было бы не столько практическим риском для безопасности, сколько вопросом скорости.Если вы говорите, что это контент, то я бы посоветовал использовать только эхо или <iframe> решение.

Но в любом случае попробуйте включить упаковщики URL-адресов через .htaccess php_flag allow_url_fopen 1 для простоты.В противном случае ваш подход к завитку выглядит нормально.Однако require не работает со строковым содержимым, а только с файлами.То, что вы пытаетесь сделать, по сути:

eval($contents);

Чтобы избежать стигмы, вы можете использовать:

require(file_put_contents(tempnam("/tmp", "rem_"), $contents));
0 голосов
/ 19 марта 2011

Хотя я ручаюсь за риск, связанный с удаленным включением кода, его иногда нельзя избежать.

Поэтому вместо того, чтобы говорить «нет, точка», было бы лучше для общего блага на самом делерассмотрите возможность.

Прежде всего, вы должны получать удаленные данные через IP-адрес напрямую, а не с помощью DNS.Это значительно уменьшит поверхность атаки.

Следующий совет, который я могу дать, это то, что вы читаете это через безопасное (SSL) соединение - оно не может быть намного лучше, чем это.Знайте, что вы можете использовать свои собственные сертификаты.Важно то, что соединение зашифровано.

Что касается выполнения кода локально, есть несколько способов сделать это:

  • Использование eval: легко, но этоогромная производительность.
  • Сохранение в файл и требующий его: я бы предложил этот.Убедитесь, что вы используете случайное имя файла, чтобы скрыть код от посторонних глаз.Или просто сохраните его вне корня документа.Это отличный шанс использовать механизм кэширования.

Заключение

https://123.145.168.190/file.txt намного безопаснее, чем http://mydomain/file.txt, даже если сертификат безопасностиэто ваш личный.Хотя вы можете отключить проверку сертификата в curl - это легко сделать.

0 голосов
/ 19 марта 2011

Если вы только пытаетесь отобразить вывод , созданный удаленно, тогда вы можете просто echo $contents; после вызова curl.Одно это относительно безвредно, если вы доверяете этому источнику для создания выходных данных для ваших пользователей.

То, что другие говорили об опасностях удаленного require / include, полностью верно и правильно, и вы не должныпытаясь это при любых обстоятельствах, когда-либо .

0 голосов
/ 19 марта 2011

Боюсь, это не сработает.Получая php-файл через curl, вы получаете не источник php, а сгенерированный вывод.Единственный способ, которым это будет работать, это каким-то образом получить исходный файл php с помощью curl (например, сохранить файл php в формате .txt), но это - HUUUGE риск для безопасности, если все сделано неправильно, поэтому я просто забудуоб этом если честно!

0 голосов
/ 19 марта 2011

Вместо того, чтобы пытаться включить удаленный файл, который представляет огромную угрозу безопасности - просто сделайте так, чтобы этот удаленный файл генерировал необходимые данные и отправлял их в виде сериализованной / json-строки / xml (в зависимости от того, что проще).

Подумайте, что произойдет, если удаленный сервер будет взломан и этот файл будет заменен чем-то вредоносным.Теперь вы высосали враждебный код и выполняете его на своем сервере.Удаленная загрузка кода никогда не бывает хорошей идеей, даже если среда полностью контролируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...