原文通過 str_replace 黑名單過濾 and、select、union 等關鍵字,**極其危險**:
UnIoN、SeLeCt/*!UNION*/、0x73656c656374// 白名單驗證:只允許預期格式
function validateUsername(string $input): string {
if (!preg_match('/^[a-zA-Z0-9_\x{4e00}-\x{9fa5}]{3,20}$/u', $input)) {
throw new \Exception('用戶名僅支持中英數下劃線,3-20 位');
}
return $input;
}
// 類型/長度/範圍強制
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, ['options'=>['min_range'=>1, 'max_range'=>120]]);
// mysqli
$stmt = $mysqli->prepare('SELECT * FROM users WHERE username=? AND status=?');
$stmt->bind_param('si', $username, $status);
$stmt->execute();
// PDO(推薦)
$stmt = $pdo->prepare('SELECT * FROM users WHERE username=:u AND status=:s');
$stmt->execute([':u'=>$username, ':s'=>$status]);
// HTML 上下文 echo htmlspecialchars($userInput, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); // JavaScript 上下文 echo json_encode($userInput, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); // URL 參數上下文 echo urlencode($userInput); // 或 rawurlencode
function cleanText(string $text, int $maxLen = 1000): string {
// 1. 移除控制字符(保留換行/制表可選)
$text = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $text);
// 2. 統一換行
$text = str_replace(["\r\n", "\r"], "\n", $text);
// 3. 限制長度
if (mb_strlen($text, 'UTF-8') > $maxLen) {
$text = mb_substr($text, 0, $maxLen, 'UTF-8');
}
// 4. 去首尾空白
return trim($text);
}
composer require ezyang/htmlpurifier
require_once 'vendor/autoload.php';
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.Allowed', 'p,b,strong,i,em,u,strike,ul,ol,li,br,a[href|title],img[src|alt|width|height]');
$config->set('URI.AllowedSchemes', ['http'=>true, 'https'=>true, 'mailto'=>true]);
$purifier = new HTMLPurifier($config);
$safeHtml = $purifier->purify($dirtyHtml);
function safeFilename(string $original): string {
$ext = strtolower(pathinfo($original, PATHINFO_EXTENSION));
$allowExt = ['jpg','jpeg','png','gif','webp','pdf','doc','docx','xls','xlsx'];
if (!in_array($ext, $allowExt, true)) $ext = 'bin';
return bin2hex(random_bytes(16)) . '.' . $ext;
}
str_replace 過濾 SQL 關鍵字。escapeshellarg、realpath 校驗。