提供一個 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 "
$_POST['to'] 直接用於 copy() 目標路徑,攻擊者可寫入任意位置(如 Web 目錄植入 Webshell)。
// 修正:限制儲存目錄、檔名安全化
$allowedDir = '/var/www/downloads/';
$filename = basename($_POST['to']);
$filename = preg_replace('/[^a-zA-Z0-9._-]/', '', $filename);
$target = $allowedDir . $filename;
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');
}
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);
任何人訪問均可執行下載,需加入登入驗證、CSRF Token、速率限制。
原始代碼僅適合受信任的內網環境快速測試。公開環境必須實施上述所有防護,建議採用成熟的檔案管理系統或雲存儲 SDK。