我担心在一些类似这样的代码中使用 spring 的 JdbcTemplate 进行 SQL 注入:
jdbcTemplate.query("SELECT * FROM " + tableName, new TableMapper());
“tableName”变量是通过串联添加的,因为无法将其作为 JdbcTemplate 的参数传递。
“tableName”变量只能由管理员编辑,但我想知道技术上是否可以对此查询进行 SQL 注入攻击。
否则你能描述一个安全的方法吗?
String prepQuery = "INSERT INTO $tabname ( name, dataid, groupid, uniqueid, type, filecontainer, filetype, fileurl, filepath, uploadstatus) VALUES (?,?,?,?,?,?,?,?,?,?)";
Object[] params = new Object[] {
name,
dataid,
groupid,
uniqueid,
type,
container,
filetype,
file_url,
path,
filePresent
};
prepQuery = prepQuery.replace("$tableName",dataid);
int i = jdbcTemplate.update(prepQuery ,params);
这只是一个替代方案,但表名不能以动态方式传递。
参考文档
这是使用 Java 17+ 的改进答案
String prepQuery = "INSERT INTO %s( name, dataid, groupid, uniqueid, type, filecontainer, filetype, fileurl, filepath, uploadstatus) VALUES (?,?,?,?,?,?,?,?,?,?)";
Object[] params = new Object[] {
name,
dataid,
groupid,
uniqueid,
type,
container,
filetype,
file_url,
path,
filePresent
};
int i = jdbcTemplate.update(prepQuery.formatted(dataid) ,params);
注意:将查询更改为使用
%s
。这使用了 String::format
的实例版本,称为 formatted
是的,这是可能的。我建议像这样修改你的代码:
jdbcTemplate.query("SELECT * FROM ?", new Object[]{tableName},new TableMapper());
这可以安全地将 tableName 插入到您的查询中;)