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

PHP 開發安全鐵律:過濾輸入、防 SQL 注入、XSS、CSRF 完整防護指南

     編輯:PHP 綜合知識

鐵律 1:永不信任外部資料

所有非程式碼直接撰寫的資料皆為「受汙染」:

  • $_GET、$_POST、$_REQUEST
  • $_COOKIE、$_SESSION(可被竄改)
  • 資料庫查詢結果、API 回應、檔案內容

汙染範例

$username = $_POST['username']; // 汙染!
$safe = cleanInput($username);   // 淨化後才可用

簡易淨化函式

function cleanInput($input) {
    $clean = strtolower($input);
    $clean = preg_replace('/[^a-z]/', '', $clean); // 僅保留字母
    return substr($clean, 0, 12); // 限制長度
}

鐵律 2:關閉危險 PHP 設定

  • register_globals = Off(PHP 5.4+ 已移除)
  • magic_quotes_gpc = Off(PHP 5.4+ 已移除)
  • display_errors = Off(生產環境)
  • error_reporting = E_ALL & ~E_NOTICE

鐵律 3:看不懂的代碼無法保護

保持程式碼清晰、單一職責、避免過度壓縮邏輯:

// 難以審計
$input = isset($_POST['u']) ? $_POST['u'] : '';

// 易審計
$input = '';
if (isset($_POST['username'])) {
    $input = $_POST['username'];
}

鐵律 4:縱深防禦

同一風險點**多層防護**:

  • 前端 JS 驗證(用戶體驗)
  • 後端格式/長度/型別驗證
  • 資料庫層預備語句防注入
  • 輸出端語境編碼防 XSS

實戰:防 SQL 注入

危險寫法

$sql = "SELECT * FROM users WHERE user='{$_POST['user']}' AND pass='{$_POST['pass']}'";

輸入 ' OR '1'='1 繞過驗證。

正確寫法(PDO 預備語句)

$stmt = $pdo->prepare("SELECT * FROM users WHERE user=? AND pass=?");
$stmt->execute([$_POST['user'], $_POST['pass']]);

實戰:防 GET 參數竄改

白名單驗證

$pid = $_GET['pid'];
if (!preg_match('/^[0-9]{1,5}$/', $pid)) {
    die('非法參數');
}
// 縱深:資料庫層再次 escape
$sql = "SELECT * FROM page WHERE pid='" . $pdo->quote($pid) . "'";

實戰:防緩衝區溢位

// 前端限制


// 後端截斷
$name = substr($_POST['name'], 0, 40);

// 清除十六進位注入嘗試
$name = preg_replace('/\\\\x[0-9a-fA-F]{1,3}/', '', $name);

實戰:防 XSS(跨站腳本)

// 輸出到 HTML 內容
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');

// 輸出到 JavaScript
echo json_encode($userInput);

// 輸出到 URL
echo urlencode($userInput);

// 允許有限標籤
echo strip_tags($input, '');

實戰:防表單竄改(隱藏欄位)

隱藏欄位 <input type="hidden" name="table" value="users"> 可被工具竄改。
**對策**:伺服端**不可信任**隱藏欄位,權限控制靠 Session/Token。

實戰:防遠程表單提交(CSRF)

<?php
session_start();
$token = md5(uniqid(rand(), true));
$_SESSION['csrf_token'] = $token;
?>
...
<?php if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) { die('CSRF 驗證失敗'); } // 處理表單... ?>

總結檢查清單

風險核心對策縱深措施
SQL 注入預備語句輸入白名單、最小權限 DB 帳號
XSS輸出語境編碼CSP 標頭、HttpOnly Cookie
CSRF同步 Token 驗證SameSite Cookie、Referer 檢查
參數竄改白名單驗證簽名/加密關鍵參數
檔案上傳型別/大小/副檔名驗證儲存非網頁目錄、重新命名、掃毒
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved