当前位置: 首页
数据库
JSON扩展字段SQL注入防御方法解析与参数绑定实践

JSON扩展字段SQL注入防御方法解析与参数绑定实践

热心网友 时间:2026-05-08
转载
# JSON字段解析后直接拼进SQL字符串,等于开门揖盗 只要把解析出来的JSON值(比如 `user.get("name")`)用 `+` 或 `String.format()` 塞进SQL字符串里,就立刻回到高危状态。哪怕前面用了 `ObjectMapper.readValue()`、做了非空校验、甚至trim了空格,都拦不住 `' OR '1'='1` 这类输入。数据库只认语法,不认“你本意是不是想查数据”。 **常见错误现象**: - `MySQLSyntaxErrorException` 频发但SQL日志里看不出明显语法错 - 某次传 `{"status":"active' -- "}` 后查询返回全部记录 - 后台日志出现 `UNION SELECT` 或 `EXTRACTVALUE` 等报错注入特征 **必须遵守的铁律**: 1. 所有JSON解析结果(`JsonNode.asText()`、`Map.get()`、`object.field`)都必须视为不可信输入 2. 禁止对JSON字段做任何“看起来安全”的假设——比如认为status只能是active/inactive,就跳过参数化 3. 如果JSON结构固定,优先用Jackson的 `@JsonProperty` + POJO绑定,而非泛型 `Map` ## MyBatis中JSON字段必须用 `#{}`,禁用 `${}` `${}` 是字符串替换,JSON字段值进去就是裸奔;`#{}` 才走PreparedStatement预编译。哪怕字段名来自JSON,只要它是值(不是表名、排序字段),就必须走 `#{}`。 **使用场景**:用户提交 `{"filter":{"name":"admin","age":25}}`,后端解析后用于WHERE条件。 **正确写法**: ```sql WHERE name = #{filter.name} AND age = #{filter.age} ``` **错误写法**: ```sql WHERE name = '${filter.name}' # 单引号包着也无效 ``` **关键细节**: - 模糊查询要加 `concat('%', #{keyword}, '%')`,不能写成 `"%${keyword}%"` - 如果JSON里嵌套了数组(如 `{"ids":[1,2,3]}`),需转成 `IN (?, ?, ?)` 形式,用MyBatis的 `` 动态生成占位符 ## 动态字段名(如JSON中的 `sortField`)必须白名单硬校验 JSON里如果带 `{"sort":"email DESC"}` 这种字段,`ORDER BY ?` 会直接报错——预编译不支持结构参数。这时候不能妥协用 `String.format("ORDER BY %s", sort)`,得靠白名单+正则双保险。 性能影响几乎为零,但漏掉一个字符就可能被绕过。 **白名单校验四步法**: 1. **定义明确白名单**:`Set.of("id", "name", "email", "created_at")` 2. **方向单独校验**:`if (!"ASC".equals(dir) && !"DESC".equals(dir)) throw new IllegalArgumentException();` 3. **完整匹配组合**:`"email DESC"` 必须整体在白名单中,不能只校验 `email` 部分 4. **拒绝特殊字符**:用 `sort.trim().replaceAll("\s+", " ")` 规范化后再比对,拒绝任何空白符、Unicode分隔符、不可见字符 ## JSON路径表达式也要参数化 MySQL 8.0+ 和 PostgreSQL 的 JSON 函数虽支持路径字符串,但路径本身若来自用户输入(比如前端传 `path: "$.settings.theme"`),仍可能被构造为 `"$.settings.theme' OR '1'='1"` 导致注入。路径不是值,但它是执行上下文的一部分。 **容易踩的坑**:以为JSON函数自动免疫,结果在 `WHERE JSON_EXTRACT(data, ?) = ?` 里只对右边的值参数化,左边路径没处理。 **防护措施**: - 路径字段必须走白名单:`if (!allowedPaths.contains(path)) throw ...` - 禁止拼接路径字符串:`"$.user." + userInput` 是典型错误 - PostgreSQL 的 `->>` 操作符同理,`json_col ->> ?` 不合法,必须先校验再硬编码 - 如果业务真需要动态路径,改用存储过程封装校验逻辑,应用层只传索引或枚举key ## 总结 JSON字段解析和SQL绑定之间那层薄薄的“信任”,是最容易被忽略的攻击面。参数化不是写了 `#{}` 就万事大吉,而是每个从JSON里掏出来的值,都要重新经历“是否可信→是否白名单→是否参数化”的三重判断。
来源:https://www.php.cn/faq/2414983.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
Redis延迟双删策略实现方法与实战示例

Redis延迟双删策略实现方法与实战示例

在缓存与数据库协同工作的经典模式中,Cache-Aside(旁路缓存)策略因其简洁高效而被广泛采用。然而,在高并发场景下,一个棘手的问题常常浮出水面:并发读写可能导致缓存被回填旧值,从而引发数据不一致。为了解决这个痛点,延迟双删(Delayed Double Deletion)方案应运而生,它是对C

时间:2026-05-08 08:45
MySQL复杂查询CPU飙升原因解析语法检查与计算节点开销详解

MySQL复杂查询CPU飙升原因解析语法检查与计算节点开销详解

MySQL复杂查询CPU飙升:解析器与优化器的“隐形战场” 说起MySQL复杂查询导致CPU飙升,很多人的第一反应是“数据量太大”或者“磁盘IO跟不上”。其实,真正的瓶颈往往不在数据读取本身,而在于查询“起飞”前的准备工作。当一条SQL包含嵌套子查询、多层JOIN,或者使用了非确定性函数时,解析器和

时间:2026-05-08 08:13
MySQL设置自增初始值教程 修改auto_increment实现多主复制

MySQL设置自增初始值教程 修改auto_increment实现多主复制

在MySQL双主架构中,为避免自增ID冲突,必须配对设置auto_increment_increment与auto_increment_offset参数。例如将步长设为2,两主库偏移量分别设为1和2,可生成错开的奇偶ID序列。配置需写入my cnf文件并重启服务以永久生效,同时确保server-id唯一并开启log_slave_updates,从而构建稳定的

时间:2026-05-08 08:13
MySQL 5.7 与 8.0 版本 JSON 功能及索引支持对比详解

MySQL 5.7 与 8.0 版本 JSON 功能及索引支持对比详解

MySQL5 7支持JSON类型与基础函数,但需通过生成列实现索引,且不支持部分更新。MySQL8 0则引入了真正的JSON部分更新和函数索引,无需生成列中转,并新增了聚合函数等增强功能。升级至8 0需手动创建函数索引、重写查询并测试字符集兼容性。

时间:2026-05-08 08:13
JSON扩展字段SQL注入防御方法解析与参数绑定实践

JSON扩展字段SQL注入防御方法解析与参数绑定实践

JSON字段解析后直接拼接SQL字符串存在严重注入风险。必须将所有JSON解析结果视为不可信输入,并严格使用参数化绑定(如MyBatis的` {}`)。动态字段名需通过白名单硬校验,JSON路径表达式同样需参数化或白名单控制。参数化需贯穿每个从JSON提取的值,杜绝信任假设。

时间:2026-05-08 08:12
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜
热门教程
更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程