開發人員、DBA、運維在將 PHP 應用部署至生產環境前,必須落實以下 5 項預防性安全措施。大多數只需幾行代碼或配置調整,卻能阻擋絕大多數常見攻擊向量。
第三方應用(CMS、框架)安裝完成後,務必刪除或重命名安裝目錄。若需保留(如多站點部署),使用 .htaccess 實施基本認證:
AuthType Basic
AuthName "Administrators Only"
AuthUserFile /usr/local/apache/passwd/passwords
Require valid-user
未授權用戶訪問將彈出登錄框,密碼驗證通過 htpasswd 生成的文件。
包含敏感信息(DB 憑證、API Key、加密鹽)的配置文件禁止使用 .inc、.config 等非 PHP 擴展名。原因:
.inc,直接作為文本下載/顯示,導致機密洩露config.php,PHP 引擎會解析執行,不會輸出源碼<?php
// config.php - 安全
define('DB_HOST', 'localhost');
define('DB_PASS', 's3cr3t');
// 直接訪問輸出空白(無輸出語句)
| 算法 | 位長 | 狀態 | PHP 函數 |
|---|---|---|---|
| MD5 | 128-bit | ❌ 極不安全(彩虹表/碰撞) | md5() |
| SHA-1 | 160-bit | ❌ 已被破解 | sha1() |
| SHA-256 | 256-bit | ⚠️ 計算太快,需配合鹽+多輪 | hash('sha256', ...) |
| bcrypt | 184-bit | ✅ 推薦(內置鹽、可調成本) | password_hash() |
| Argon2id | 256-bit | ✅ 現代首選(抗側通道、記憶體硬度) | password_hash(..., PASSWORD_ARGON2ID) |
<?php
// 註冊:自動生成鹽、成本因子、算法標識
$hash = password_hash($password, PASSWORD_DEFAULT); // 當前為 bcrypt
// 或顯式指定 Argon2id (PHP 7.2+)
$hash = password_hash($password, PASSWORD_ARGON2ID);
// 登錄驗證:自動解析 hash 中的算法/鹽/成本
if (password_verify($input_password, $stored_hash)) {
// 成功
// 可選:檢查是否需重新哈希(如成本因子變更)
if (password_needs_rehash($stored_hash, PASSWORD_DEFAULT)) {
$new_hash = password_hash($input_password, PASSWORD_DEFAULT);
// 更新數據庫
}
}
register_globals = On 會將 $_GET/$_POST/$_COOKIE 變量自動註冊為全局變量,導致:
$is_admin = true)檢查方法:phpinfo() 查看 register_globals,或 ini_get('register_globals')。必須為 Off。主流框架(Laravel、Symfony、ThinkPHP、Joomla、Drupal)安裝腳本均會強制檢查並報錯。
所有業務關鍵變量在使用前必須顯式初始化,防止未定義變量被外部注入:
<?php
// ❌ 危險:$auth 未初始化,若 register_globals=On 可被 URL 注入 ?auth=1
if ($auth) { grant_access(); }
// ✅ 安全:顯式初始化
$auth = false;
if (check_credentials($user, $pass)) {
$auth = true;
}
if ($auth) { grant_access(); }
配合 error_reporting(E_ALL) 開發環境捕獲未定義變量通知,declare(strict_types=1) 強制類型聲明(PHP 7+)。
htmlspecialchars($str, ENT_QUOTES, 'UTF-8'),CSP 頭部session.cookie_httponly=1、session.cookie_secure=1(HTTPS)、定期重生成 IDdisplay_errors=Off、log_errors=On安全非一次性動作,而是持續的過程。將以上措施納入部署清單、代碼審查清單、CI/CD 流水線,構建纵深防禦體系。