目录
1、问题
2、原因
3、修改
1、问题
代码进行sonar扫描,扫描出存在sql注入问题。 问题代码如下:
//预编译
preparedStatement = conn.prepareStatement(sql);
//参数
initQueryParams(queryParams, preparedStatement);
//查询结果
resultSet = preparedStatement.executeQuery();
2、原因
因为用到了conn.prepareStatement,就感觉已经使用了预编译,应该没有sonar问题。因此找到了质量组申诉误报,然后他们给出结论如下:
(1)sql是接口传的,可能是delete、update影响比较大
(2)sql就算是查询sql,如果sql占位符是 ${}也没有真的实现预编译
如,select * from test where id = ${id},其实没有用到预编译
#、$区别
#预编译会替换成?, $直接进行的字符替换。
数据表或者order by后面的动态参数,必须用${},参数用#{}
如:select * from ${test} where id =#{id} order by ${order}
3、修改
(1)增加sql校验,校验sql是select语句
public static SwaggerResultUtil<String> checkSql(String sql, DbType dbType) {
// 检测是否有语法错误
try {
SQLUtils.parseStatements(sql, dbType);
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);
SQLStatement statement = parser.parseStatement();
// 只允许查询语句
if (!(statement instanceof SQLSelectStatement)) {
return SwaggerResultUtil.resultError(ExceptionCodeUtil.PARAM_ERROR_CODE_I4, "必须是select语句");
}
} catch (Exception e) {
log.error("sql有语法错误,错误信息:", e);
return SwaggerResultUtil.resultError(ExceptionCodeUtil.PARAM_ERROR_CODE_I4, "sql语法错误:" + e.getMessage());
}
return SwaggerResultUtil.resultSuccess();
}
(2)sql做替换${},换成?
根据业务,正常通过页面访问的sql,数据表是写死的,只有参数是动态的,所以用下面替换
sql = sql.replaceAll("\\$\\{\\w*\\}", "?");















![HTB:Nibbles[WriteUP]](https://i-blog.csdnimg.cn/direct/c4ca5cfb41ae4e949faf5b379c982854.png)



