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

PHP 防盜鏈下載實現:Referer 驗證與安全跳轉

     編輯:PHP 綜合知識

防盜鏈核心在於驗證 HTTP Referer 標頭,僅允許白名單域名的請求訪問下載資源。本文提供一個完整的 PHP 實現,包含白名單配置、多下載地址支援、Referer 解析驗證、安全重定向等功能。

核心代碼實現

<?php
// config.php - 配置文件
return [
    'default_url' => 'https://www.example.com/404.html', // 非法請求跳轉地址
    'allowed_domains' => [                                // 白名單域名
        'https://www.example.com/',
        'https://example.com/',
    ],
    'download_paths' => [                                 // 下載路徑映射
        1 => '/var/www/downloads/area1/',
        2 => '/var/www/downloads/area2/',
    ],
];

// download.php - 下載入口
require_once 'config.php';
$config = require 'config.php';

$referer = $_SERVER['HTTP_REFERER'] ?? '';
$site_id = isset($_GET['site']) ? (int)$_GET['site'] : 0;
$filename = isset($_GET['file']) ? basename($_GET['file']) : '';

// 1. Referer 為空直接攔截
if (empty($referer)) {
    header("Location: {$config['default_url']}");
    exit;
}

// 2. 驗證 Referer 域名是否在白名單
$allowed = false;
foreach ($config['allowed_domains'] as $domain) {
    if (strpos($referer, $domain) === 0) { // 嚴格前綴匹配
        $allowed = true;
        break;
    }
}

if (!$allowed) {
    header("Location: {$config['default_url']}");
    exit;
}

// 3. 驗證下載路徑是否存在
if (!isset($config['download_paths'][$site_id])) {
    header("Location: {$config['default_url']}");
    exit;
}

$filepath = $config['download_paths'][$site_id] . $filename;

// 4. 安全檢查:防止目錄遍歷攻擊
$real_base = realpath($config['download_paths'][$site_id]);
$real_file = realpath($filepath);

if ($real_file === false || strpos($real_file, $real_base) !== 0) {
    header("Location: {$config['default_url']}");
    exit;
}

// 5. 文件存在性檢查
if (!is_file($real_file)) {
    header("Location: {$config['default_url']}");
    exit;
}

// 6. 輸出文件(大文件建議用 X-Sendfile 或 Nginx X-Accel-Redirect)
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Length: ' . filesize($real_file));
readfile($real_file);
exit;

關鍵安全點解析

1. Referer 可偽造,需多層防護

HTTP Referer 由客戶端發送,可被篡改或攔截。生產環境建議結合:

  • 簽名 URL:下載鏈接帶時間戳 + HMAC 簽名,服務端驗證
  • Token 機制:用戶登錄後生成一次性下載 Token,驗證後失效
  • Nginx 防盜鏈模塊:在 Web 服務器層面攔截(性能更好)

2. 文件路徑安全

使用 basename() 獲取文件名,realpath() 解析絕對路徑,嚴格檢查文件是否在允許目錄內,防止 ../../etc/passwd 類遍歷攻擊。

3. 大文件傳輸優化

readfile() 會將文件讀入內存再輸出,大文件易導致內存溢出。推薦:

  • Apache:mod_xsendfile + header('X-Sendfile: ' . $real_file)
  • Nginx:X-Accel-Redirect 內部重定向
  • PHP:分塊輸出 while(!feof($fp)) echo fread($fp, 8192);

使用示例

下載鏈接格式:

https://www.example.com/download.php?site=1&file=manual.pdf

頁面嵌入:

<a href="/download.php?site=1&file=manual.pdf">下載手冊</a>

總結

基於 Referer 的防盜鏈屬於「誠實用戶」防護,能阻擋 90% 以上的直接外鏈盜取。對於高價值資源,務必結合簽名 URL、用戶認證、Web 服務器層防護構建多層防線。

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