java - java代码中的SQL注入问题
问题描述
当扫描编码标准/规则时,我有以下主要方法显示 SQL 注入缺陷(因为这里完成了字符串连接)。
public static void main(String[] args) {
boolean flag = false;
String name = "";
String subName = "abhi";
try {
Class.forName("org.postgresql.Driver");
Connection c = DriverManager.getConnection("url","user", "password");
if(flag==true){
name = "LIKE '%'";
} else {
name = "= LOWER('" + subName + "')";
}
Statement s = c.createStatement();
String query = "SELECT * FROM xyz WHERE name "+name;
ResultSet rs = s.executeQuery(query);
while(rs.next()){
System.out.println(":"+rs.getString(1));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException se) {
se.printStackTrace();
}
}
我想删除 SQL 注入漏洞。由于我的name
参数是动态的,我不能用preparedStatement
. 什么是最佳解决方案?
注意:在块中使用 2 个不同的查询if-else
不会解决目的,因为我有 7 个不同的参数要动态设置,这将引入开销,因为会有很多查询。
解决方案
由于我的名称参数是动态的,我无法使用preparedStatement 进行设置。
当然可以,您只需要同时动态处理 SQL 文本和参数。
您还应该使用try-with-resources来正确关闭Connection
、PreparedStatement
和ResultSet
对象。
boolean flag = false;
String subName = "abhi";
try (Connection c = DriverManager.getConnection("url","user", "password")) {
String sql = "SELECT *" +
" FROM xyz" +
" WHERE name " + (flag ? "LIKE '%'"
: "= LOWER(?)");
try (PreparedStatement s = c.prepareStatement(sql)) {
if (! flag)
s.setString(1, subName);
try (ResultSet rs = s.executeQuery()) {
while (rs.next()) {
System.out.println(":"+rs.getString(1));
}
}
}
} catch (SQLException se) {
se.printStackTrace();
}
仅供参考: WHERE name LIKE '%'
与 相同,如果列不可为空WHERE name IS NOT NULL
,则与 noWHERE
子句相同。name
推荐阅读
- sql - ORACLE - 在大表上设置重复的排名,需要优化
- android - 我能知道输入变量为什么它总是给我错误,非常感谢
- java - 用户输入值后在 Java 中循环
- amazon-web-services - 当 AWS Glue 工作流程完成时,是否可以发布到 SNS?
- javascript - 类似数组/映射的数据结构,具有对项目的唯一 ID 支持、O(1) get() 方法且无重复
- python - 卸载 Python3.8 ,我会丢失所有已安装的软件包吗?
- java - 将日期转换为 LocalDateTime,格式为“yyyy-MM-dd HH:mm:ssXXX”
- c - 如何将具有未知小数的浮点数转换为整数而不会丢失数据?
- python - Selenium Python - 元素拦截错误
- django - Elastic Beanstalk - 从自定义域浏览站点时 - DNS_PROBE_FINISHED_NXDOMAIN