Безопасно ли использовать fopen для выполнения cURL с загрузкой файлов? - PullRequest
1 голос
/ 25 апреля 2019

В настоящее время у меня есть форма загрузки, которая отправляет файл в Dropbox через его API.Файл .php, который получает файл после выполнения cURL, выглядит следующим образом:

$localFile = $_FILES["file_key"]['tmp_name'];
$fp = fopen($localFile, 'r');

$ch = curl_init();

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_URL, 'https://content.dropboxapi.com/2/files/upload');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "authorization: Bearer MY-TOKEN",
    "content-type: application/octet-stream",
    "dropbox-api-arg: {\"path\": \"/tmp/a.txt\",\"mode\": \"add\",\"autorename\": true,\"mute\": false,\"strict_conflict\": false}"
));
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 86400); // 1 Day Timeout
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_BUFFERSIZE, 128);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localFile));
curl_exec ($ch);

Это прекрасно работает, но меня беспокоит вопрос о fopen во второй строке.Это плохая практика?Можно ли получить вредоносный файл и сломать систему, несмотря на то, что он доступен только для чтения?

Ответы [ 3 ]

0 голосов
/ 25 апреля 2019

Да, это безопасно, если вы используете режим только для чтения, поскольку файл не выполняется, содержимое просто читается.

0 голосов
/ 25 апреля 2019

это правильный способ сделать это, если вы используете Linux или MacOS * или * BSD и не заботитесь о совместимости с Windows, но все же я хочу воспользоваться вашим кодом:

Если вы когда-нибудь напишите какой-либо код, который может работать в Windows, установите привычку использовать режим fopen rb вместо r, потому что режим fopen r в окнах может повредить двоичные данные (и это происходит из-за вашего * 1006). * header, это двоичные данные) и linux / macos / * BSD обрабатывают режимы r и rb одинаково, поэтому сделайте его

$fp = fopen($localFile, 'rb');

и эта строка

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "authorization: Bearer MY-TOKEN",
    "content-type: application/octet-stream",
    "dropbox-api-arg: {\"path\": \"/tmp/a.txt\",\"mode\": \"add\",\"autorename\": true,\"mute\": false,\"strict_conflict\": false}"
));

должен на самом деле читать

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "authorization: Bearer MY-TOKEN",
    "content-type: application/octet-stream",
    "dropbox-api-arg: " . json_encode(array(
        'path' => '/tmp/a.txt',
        'mode' => 'add',
        'autorename' => true,
        'mute' => false,
        'strict_conflict' => false,
    ))
));

он просто более читабелен, более удобен в обслуживании и его легче модифицировать. хотя я должен сказать, что размещение этих данных в качестве заголовка HTTP было плохим дизайнерским решением со стороны Dropbox, есть символы, которые являются недопустимыми в заголовках HTTP, которые являются совершенно допустимыми в именах файлов по большинству стандартов файловой системы, то есть я подозреваю, что возможно создать правильный json, содержащий допустимое имя файла, которое не может быть закодировано в http-заголовке ... они должны были использовать вместо этого multipart / form-data и просто поместить файл и json как две отдельные переменные формы, imo.

0 голосов
/ 25 апреля 2019

Это совершенно безопасно. PHP читает это как чистые данные, он не пытается выполнить это. curl просто передаст его в API DropBox. В этот момент это проблема DropBox (и было бы весьма удивительно, если бы они выполняли код, загружаемый пользователями, если у них нет серьезных недостатков безопасности).

...