You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保JdbcTemplate仅执行SELECT语句而非DDL/DML语句?

问题解答

仅靠jdbcTemplate.queryForList(sql)没法完全确保只执行纯SELECT语句——你测试里普通DML/DDL抛异常,只是因为这类语句默认不返回结果集,但确实存在既能返回结果集又能修改数据的SQL语句,会绕过这个限制。

现有方式的漏洞点

queryForList底层调用JDBC的executeQuery()方法,要求语句必须返回结果集。普通的INSERT/UPDATE/DELETE或CREATE TABLE这类语句不返回结果集,所以会报错,但以下场景能突破这个限制:

  • 带返回子句的DML语句:比如PostgreSQL的INSERT INTO users(name) VALUES('foo') RETURNING *,执行插入操作的同时会返回插入的行数据;SQL Server的INSERT INTO users(name) VALUES('foo') OUTPUT inserted.*同理,这类语句会返回结果集,queryForList会执行成功,同时数据已被修改。
  • 调用特定存储过程:如果存储过程内部执行了DML/DDL操作,同时通过SELECT返回结果集,queryForList也能执行该存储过程,导致数据被修改。

真正确保仅执行SELECT的方案

需要多层防护来彻底解决问题:

  • 数据库权限控制(最关键):给执行SQL的数据库账号仅授予SELECT权限,即使有恶意语句,数据库层面会直接拒绝执行(比如无INSERT权限时,带RETURNING的INSERT也会报错)。
  • SQL语法校验:执行前对SQL做校验,比如检查语句是否以SELECT开头(需处理注释、空格等特殊情况,比如/* 注释 */ SELECT ...);更严谨的方式是用SQL解析库(如JSqlParser、Apache Calcite)解析SQL语法树,判断是否仅包含SELECT操作,无DML/DDL相关节点。
  • 避免任意SQL输入:如果业务允许,尽量提供预设查询模板,让用户仅选择或填写参数,从根源降低风险。

内容的提问来源于stack exchange,提问作者amerty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:40:10