首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 實現遠程檔案下載與傳輸的簡易方案

     編輯:PHP 綜合知識

功能場景

提供一個 Web 介面,讓使用者輸入遠程 URL 與本地儲存路徑,伺服器端執行下載並顯示傳輸結果。適用於伺服器間檔案遷移、備份下載等場景。

核心實現

if ($_GET['xfer']) {
    if ($_POST['from'] == "") {
        print "You forgot to enter a url.";
    } else {
        copy($_POST['from'], $_POST['to']);
        $size = round((filesize($_POST['to'])/1000000), 3);
        print "transfer complete.
$_POST[from]
$_POST[to] : $size MB"; } } else { print "
from(https://):
to(filename):
"; }

關鍵風險與修正(必讀)

1. 任意檔案寫入漏洞

$_POST['to'] 直接用於 copy() 目標路徑,攻擊者可寫入任意位置(如 Web 目錄植入 Webshell)。

// 修正:限制儲存目錄、檔名安全化
$allowedDir = '/var/www/downloads/';
$filename = basename($_POST['to']);
$filename = preg_replace('/[^a-zA-Z0-9._-]/', '', $filename);
$target = $allowedDir . $filename;

2. SSRF(伺服器端請求偽造)

copy() 支援多種協議(http、ftp、file、php:// 等),攻擊者可探測內網服務、讀取本地檔案。

// 修正:驗證 URL 協議、域名白名單、禁止內網 IP
$url = $_POST['from'];
$parsed = parse_url($url);
if (!in_array($parsed['scheme'], ['http', 'https'])) die('Invalid protocol');
$host = $parsed['host'];
$ip = gethostbyname($host);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
    die('Access to private/reserved IPs denied');
}

3. 大檔案記憶體/超時問題

copy() 會將整個檔案載入記憶體,大檔案導致 OOM 或超時。

// 修正:使用串流複製
$ctx = stream_context_create(['http' => ['timeout' => 300]]);
$src = fopen($url, 'rb', false, $ctx);
$dst = fopen($target, 'wb');
stream_copy_to_stream($src, $dst);
fclose($src); fclose($dst);

4. 無認證授權

任何人訪問均可執行下載,需加入登入驗證、CSRF Token、速率限制。

現代化替代方案

  • GuzzleHttp:功能豐富的 HTTP 客戶端,支援串流、重試、中介軟體
  • cURL:底層控制更精細,支援斷點續傳、限速、憑證驗證
  • 異步下載:大量任務使用 Swoole/OpenSwoole 或 ReactPHP

總結

原始代碼僅適合受信任的內網環境快速測試。公開環境必須實施上述所有防護,建議採用成熟的檔案管理系統或雲存儲 SDK。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved