使用fopen在文件上传中执行cURL是否安全?

时间:2019-04-24 21:57:38

标签: php curl file-upload dropbox-api

我目前有一个上传表单,该表单通过其API将文件发送到Dropbox。执行cURL之后将文件接收到的.php如下:

$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 :(得分:0)

这是绝对安全的。 PHP将其读取为纯数据,它不会尝试执行它。 curl只需将其传递给DropBox API。到那时,这是DropBox的问题(如果他们执行用户上传的代码,除非他们存在严重的安全漏洞,这是非常令人惊讶的。)

答案 1 :(得分:0)

是的,如果您使用只读模式,这是安全的,因为未在执行文件,因此只是在读取内容。

答案 2 :(得分:0)

如果您使用的是Linux或MacOS *或* BSD且不关心Windows兼容性,这是正确的方法,但是我仍然想对您的代码进行修改:

如果您编写了可能在Windows上运行的任何代码,请养成使用fopen模式rb而不是r的习惯,因为Windows上的fopen r模式可能会破坏二进制数据(并通过您的octet-stream标头,它是二进制数据)和linux / macos / * BSD都以相同的方式对待rrb模式,因此使它成为

$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 HEADER放置是Dropbox的错误设计决定,但HTTP头中的字符是非法的,对于大多数文件系统标准而言,这些头在文件名中都是完全合法的,这意味着我怀疑可以制作包含以下内容的有效json:一个有效的文件名,不能使用http-header编码。.他们应该改用multipart / form-data,并将文件和json放在2个单独的表单变量imo中。