sql注入防护核心是杜绝拼接用户输入,需通过参数化查询、最小权限原则、业务层校验、合理索引及错误脱敏构建多层防线。

SQL 注入防护的核心是杜绝拼接用户输入到 SQL 语句中,而查询安全优化的关键在于用最小权限原则 + 参数化查询 + 合理索引 + 业务层校验构建多层防线。
用参数化查询(预编译)替代字符串拼接
这是防御 SQL 注入最有效、最基础的手段。数据库驱动会将参数值作为独立数据处理,不会被解析为 SQL 语法。
- ✅ 正确示例(Python + SQLAlchemy):query = "SELECT * FROM users WHERE username = :name AND status = :status"
result = conn.execute(text(query), {"name": user_input, "status": "active"}) - ❌ 危险写法:query = f"SELECT * FROM users WHERE username = '{user_input}'" —— 单引号闭合后可任意注入
- 注意:ORM 的 filter()、where() 等方法默认使用参数化,但 raw SQL 或 execute() 传字符串时必须手动绑定参数
严格限制数据库账号权限
即使某处逻辑疏漏,低权限账户也能大幅降低攻击危害。
1) 用户无需考虑系统的设计、安装、维护,会上网就会操作;2) 美观、友好的展示页面,顾客可以方便地查询、订购商品; 3) 用户可以方便、自主地定义各种商品信息、调整页面布局; 4) 网站采用MD5不可逆转加密以及防SQL注入;5) 商品价格后台成批修改,创目前商城之首;
- Web 应用连接数据库的账号,只授予 必要表的 SELECT/INSERT/UPDATE 权限,禁止 DROP、ALTER、CREATE、EXECUTE、LOAD_FILE 等高危操作
- 避免使用 root 或 sa 账户;生产环境应为不同模块(如订单、用户)配置独立数据库账号
- 敏感表(如 user_credentials)可单独设只读账号,或通过视图+行级策略进一步隔离
输入校验与上下文感知过滤
参数化解决语法注入,但业务逻辑仍需主动识别异常输入。
- 对已知格式字段做白名单校验:手机号用正则
^1[3-9]\d{9}$,邮箱用标准 RFC 校验库 - 对模糊搜索类字段(如商品关键词),禁用 SQL 通配符直接透传,改用全文检索引擎(如 Elasticsearch)或转义
%、_符号 - 避免在 ORDER BY / LIMIT / 表名/列名等位置使用用户输入 —— 这些无法参数化,必须通过枚举白名单映射(如
{"sort": "price_asc" → "ORDER BY price ASC"})
启用查询审计与错误信息脱敏
防御是前提,可观测性是兜底。
- 数据库开启通用查询日志(或使用代理如 ProxySQL)记录慢查和异常模式(如含
UNION SELECT、@@version的请求) - 应用层捕获数据库异常时,绝不返回原始 SQL 或 MySQL 错误码(如 “Error 1064”),统一返回“系统繁忙”,后台记录完整堆栈和 SQL 上下文
- 定期用 SQLMap 或自研扫描器对测试环境做黑盒检测,重点覆盖登录、搜索、导出等高频接口









