防止 SQL 注入的核心是:**永远不拼接用户输入到 SQL 字符串中**。MySQL 安全写法的关键在于使用参数化查询(预处理语句),配合合理的权限控制与输入校验。
用预处理语句(Prepared Statements)代替字符串拼接
这是最有效、最通用的防御手段。PHP、Python、Java 等主流语言都支持 MySQL 的预处理接口,它把 SQL 结构和数据严格分离。
✅ 正确(PHP PDO 示例): $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND status = ?");$stmt->execute([$user_input, 1]);
$result = $stmt->fetchAll(); ❌ 危险(绝对避免): $username = $_GET['name'];
$sql = "SELECT * FROM users WHERE username = '$username'"; // 用户输 ' OR 1=1 -- 就完蛋
$pdo->query($sql);
明确字段类型,对输入做基础校验
预处理能防注入,但不能替代业务逻辑校验。比如 ID 应为整数、手机号应匹配格式、用户名不应含 SQL 特殊符号等。
对数字型参数,用 (int) 或 filter_var($id, FILTER_VALIDATE_INT) 强制转整型 对字符串长度、正则格式(如邮箱、手机号)做服务端验证,不只靠前端 敏感操作(如删除、修改密码)前,再次确认用户身份与权限,而非仅依赖 URL 参数最小权限原则配置数据库账户
应用连接 MySQL 时,不要用 root 或高权限账号。按需分配权限:
只读接口 → 只授 SELECT 用户注册 → 授 INSERT 到 user 表,禁止 UPDATE/DELETE 后台管理 → 单独账号,IP 白名单 + 二次认证 禁用 FILE、LOAD DATA、EXECUTE 等高危权限关闭错误信息暴露,启用日志审计
生产环境必须关闭详细 MySQL 错误输出(如 “You have an error in your SQL syntax…”),否则会泄露表名、字段名甚至服务器路径。
PHP 中设 display_errors = Off,用 error_log() 记录异常 MySQL 开启 general_log 或 slow_query_log(配合过滤),定期检查异常查询模式 对高频失败登录、大量报错请求做监控告警