真正有效的修复必须落在数据库访问层,禁用字符串拼接、强制使用参数化查询;网关层仅可做数字校验、长度限制等轻量初筛,无法替代参数化查询。

移动端API接口的SQL注入漏洞,不能靠网关层“过滤单引号”或“拦截UNION”来修——这类规则既易被绕过,又会误杀合法输入(比如用户昵称 O'Connor),真正有效的修复必须落在数据库访问层,且必须禁用所有字符串拼接逻辑。
参数化查询是唯一可靠防线,其他都是辅助
SQL注入的本质是代码与数据未分离。只要后端存在类似 "SELECT * FROM orders WHERE out_trade_no = '" + out_trade_no + "'" 这样的拼接,无论网关加多少正则、签名多严格,漏洞都还在。
- Java 必须用
PreparedStatement,占位符统一为?,调用setString()/setLong()设置值,绝不用String.format()或+拼接 - Python(MySQL/PostgreSQL)必须用
cursor.execute("SELECT ... WHERE id = %s", [user_id]),SQLite 用?占位符;严禁f"WHERE name = '{name}'"或.format() - Node.js(pg)必须用
client.query("SELECT ... WHERE id = $1", [id]);mysql2 同理用query("...", [params]),而非模板字符串 - ORM(如 MyBatis、Hibernate、Django ORM)也需确认是否启用了预编译模式;MyBatis 的
${}是拼接,#{}才是参数化,别混用
网关层校验只能做轻量初筛,别让它背锅
网关(Nginx/Kong/Spring Cloud Gateway)看不到 SQL 构建逻辑,它只处理 HTTP 层原始参数,所谓“防注入”只是错觉。但它可以干几件务实的事:
- 对
user_id类纯数字字段,用正则^[0-9]+$拒绝非数字请求(注意:不适用于U123这类带前缀ID) - 限制
keyword最大长度 ≤ 200 字符,防超长 payload 触发后端解析异常 - 拒绝畸形编码:如连续多个
%、未闭合的%2、含空字节%00 - 绝对不要写
if param.contains("SELECT")这类规则——日志、配置、商品名里合法出现SELECT太常见
支付回调等高危接口必须字段级白名单校验
支付宝/微信回调接口常被攻击者直打,验签只保来源可信,不保参数内容安全。哪怕签名正确,out_trade_no 里塞 ORDER-123'; DROP TABLE orders;-- 一样能进 SQL。
-
out_trade_no必须匹配正则^[a-zA-Z0-9_-]{8,64}$,显式禁止'、"、;、--、/* -
total_amount必须是严格两位小数字符串,用number_format(floatval($amount), 2, '.', '')标准化后再比对原始值,防99.999绕过 -
trade_status只允许固定枚举值(如TRADE_SUCCESS),禁止额外空格、换行、Unicode零宽字符 - 微信 ApiV3 回调解密后的 JSON,必须先转
JsonNode,再逐字段取值校验,不能直接map.get("out_trade_no")就查库
最易被忽略的是:哪怕网关放过一个看似无害的 order by 参数,后端也必须用白名单(如 ["created_at", "amount"])映射到实际字段,而不是拼进 SQL —— 动态列名无法参数化,只能靠严格白名单兜底。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











