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

PHP 四大核心安全策略:檔案系統、資料庫、輸入過濾與環境加固

     編輯:PHP 綜合知識

PHP 應用安全防護四大支柱

Web 應用安全是系統設計的核心環節。本文系統整理 PHP 四大核心安全策略:檔案系統防護、資料庫注入防禦、使用者輸入過濾、執行環境加固,提供具體程式碼範例與最佳實踐清單。

策略一:檔案系統安全

風險場景:路徑遍歷攻擊

<?php
// ❌ 危險代碼:直接使用使用者輸入刪除檔案
$username = $_POST['user_submitted_name'];
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";
unlink("$homedir/$userfile");  // 攻擊者輸入 ../etc/passwd 可刪除系統檔案
?>

防護措施

<?php
// ✅ 1. 最小權限原則:PHP 執行身份僅擁有必要目錄讀寫權
// 系統層面設定,非程式碼控制

// ✅ 2. 輸入驗證與清理
function secureDelete($username, $filename) {
    // 僅允許英數字、底線、連字號、點
    if (!preg_match('/^[\w\-\.]+$/', $filename)) {
        throw new InvalidArgumentException('非法檔案名稱');
    }
    
    // 使用 realpath 解析真實路徑並確認在允許目錄內
    $baseDir = realpath("/home/$username");
    $targetPath = realpath($baseDir . DIRECTORY_SEPARATOR . $filename);
    
    if ($targetPath === false || strpos($targetPath, $baseDir) !== 0) {
        throw new RuntimeException('路徑遍歷攻擊嘗試');
    }
    
    // 使用隨機檔名儲存,資料庫記錄對應關係
    // unlink($targetPath);  // 實際刪除
}

// ✅ 3. 避免直接操作檔案系統
// 使用資料庫記錄檔案中繼資料,軟刪除 (deleted_at 欄位)
// 定期離線任務清理實體檔案
?>

策略二:資料庫安全 (SQL Injection 防禦)

核心原則:參數化查詢

<?php
// ❌ 危險:字串拼接
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";

// ✅ PDO 參數化查詢 (推薦)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false  // 關鍵:使用真實預備語句
]);

$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND password = ?');
$stmt->execute([$username, $password]);
$user = $stmt->fetch();

// ✅ 命名參數 (可讀性佳)
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :user AND password = :pass');
$stmt->execute([':user' => $username, ':pass' => $password]);

// ✅ MySQLi 參數化
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$stmt = $mysqli->prepare('SELECT * FROM users WHERE username = ? AND password = ?');
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$result = $stmt->get_result();
?>

進階資料庫安全清單

  • 專用帳號:應用使用僅有必要權限 (SELECT/INSERT/UPDATE/DELETE) 的資料庫帳號,非 root
  • IP 白名單:資料庫僅允許應用伺服器 IP 連線
  • 敏感資料加密:密碼使用 password_hash() (bcrypt/argon2),非對稱加密儲存金鑰
  • 錯誤資訊隱藏:生產環境關閉詳細 SQL 錯誤輸出
  • ORM 使用:優先使用成熟 ORM (Doctrine, Eloquent) 內建參數化

策略三:使用者輸入過濾 (XSS/CSRF 防禦)

輸出編碼:XSS 核心防禦

<?php
// ✅ HTML 內容輸出編碼
function h($str) {
    return htmlspecialchars($str, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

// 使用
echo "<div>" . h($userInput) . "</div>";

// ✅ JavaScript 內容輸出
function jsEscape($str) {
    return json_encode($str);  // 含引號,直接嵌入 JS 字串
}
echo "<script>var input = " . jsEscape($userInput) . ";</script>";

// ✅ URL 參數編碼
echo "<a href='?search=" . urlencode($keyword) . "'>搜尋</a>";

// ✅ CSS/Style 屬性編碼 (需專用函數)
?>

輸入驗證:白名單策略

<?php
// ✅ 僅允許預期格式
function validateUsername($input) {
    // 僅英數底線,3-20 字元
    return preg_match('/^[a-zA-Z0-9_]{3,20}$/', $input);
}

function validateEmail($input) {
    return filter_var($input, FILTER_VALIDATE_EMAIL) !== false;
}

function validateUrl($input) {
    // 僅允許 http/https 協定
    return filter_var($input, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED)
        && in_array(parse_url($input, PHP_URL_SCHEME), ['http', 'https']);
}
?>

CSRF 防護:Token 驗證

<?php
// Session 中儲存 Token
session_start();
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// 表單中嵌入
echo "<input type='hidden' name='csrf_token' value='" . h($_SESSION['csrf_token']) . "'>";

// 驗證
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) {
        die('CSRF Token 驗證失效');
    }
    // 處理表單...
}
?>

推薦工具:HTML Purifier

<?php
// composer require ezyang/htmlpurifier
require_once 'vendor/autoload.php';

$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.AllowedElements', 'p,b,i,em,strong,a,ul,ol,li,br,span');
$config->set('HTML.AllowedAttributes', 'a.href,a.title,span.style');
$purifier = new HTMLPurifier($config);

$cleanHtml = $purifier->purify($dirtyHtml);
// 允許安全 HTML 標籤,移除 script, iframe, on* 事件等危險內容
?>

策略四:執行環境加固

php.ini 關鍵安全設定

; 生產環境必備設定
display_errors = Off              ; 不向瀏覽器顯示錯誤
display_startup_errors = Off
error_reporting = E_ALL           ; 記錄所有錯誤
log_errors = On
error_log = /var/log/php/error.log ; 專用錯誤日誌

expose_php = Off                  ; 隱藏 PHP 版本資訊
allow_url_fopen = Off             ; 禁止遠端檔案包含
allow_url_include = Off

session.cookie_httponly = 1       ; 防 XSS 竊取 Session
session.cookie_secure = 1         ; HTTPS 環境必開
session.cookie_samesite = Strict  ; 防 CSRF (PHP 7.3+)
session.use_strict_mode = 1       ; 拒絕未初始化 Session ID
session.gc_maxlifetime = 1440     ; 24 分鐘 GC

; 已移除的危險特性 (PHP 5.4+ 已移除)
; register_globals = Off
; magic_quotes_gpc = Off

程式碼層面加固

<?php
// ✅ 嚴格型別宣告 (PHP 7+)
declare(strict_types=1);

// ✅ 關閉錯誤顯示 (雙重保險)
ini_set('display_errors', '0');

// ✅ 設定自定義錯誤處理器
set_error_handler(function($severity, $message, $file, $line) {
    error_log("PHP Error [$severity]: $message in $file:$line");
    return true;  // 不執行內建處理
});

set_exception_handler(function(Throwable $e) {
    error_log("Uncaught Exception: " . $e->getMessage());
    // 生產環境顯示友善錯誤頁
    http_response_code(500);
    include __DIR__ . '/templates/500.php';
    exit;
});

// ✅ 使用最新 PHP 版本
// PHP 8.1+ 內建 fiber, enum, readonly, never return type 等安全增強特性
?>

安全檢查清單 (部署前必驗)

類別檢查項目驗證方式
檔案系統上傳檔案型別/大小/儲存路徑驗證嘗試上傳 .php、超大檔、路徑遍歷
資料庫所有查詢使用參數化代碼審查、SQLMap 掃描
輸入過濾所有輸出經過編碼XSS Payload 測試、CSP 標頭檢查
CSRF狀態改變操作有 Token 驗證跨站提交測試
認證授權密碼強度、限流、Session 安全暴力破解測試、Session 劫持測試
環境php.ini 安全設定生效phpinfo() 驗證、滲透測試
依賴Composer 套件無已知漏洞composer audit、Snyk 掃描

安全是持續過程而非一次性任務。建立 SDL (Security Development Lifecycle),將安全實踐融入開發全生命週期。

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