背景:我已经开始使用JDBC和MYSQL来模拟书店,所有本地项目.为了连接到数据库,我开始使用Statement,但我开始读到,当多次使用查询只更改其参数时,为这些查询使用PreparedStatement会更有效.但是,我最常阅读的优点是Pre...
背景:我已经开始使用JDBC和MYSQL来模拟书店,所有本地项目.为了连接到数据库,我开始使用Statement,但我开始读到,当多次使用查询只更改其参数时,为这些查询使用PreparedStatement会更有效.但是,我最常阅读的优点是PreparedStatements如何更好地防止SQL注入.
资料来源:
这个帖子的答案here
谷歌
教授
我的问题:
在处理参数化查询时,PreparedStatements如何更好地阻止SQL注入,甚至不同于语句?我很困惑,因为如果我理解正确,值仍然会被传递到执行的SQL语句中,这只取决于程序员清理输入.
解决方法:
你是对的,你可以自己做所有的卫生,因此注射安全.但这更容易出错,因此不太安全.换句话说,自己动手会为可能导致注入漏洞的错误带来更多机会.
一个问题是转义规则可能因DB而异.例如,标准SQL只允许使用单引号(‘foo’)中的字符串文字,因此您的卫生设施可能只会逃避那些;但是MySQL允许使用双引号(“foo”)中的字符串文字,如果你不对它们进行消毒,如果你使用MySQL,你将会受到注入攻击.
如果使用PreparedStatement,则该接口的实现由相应的JDBC驱动程序提供,该实现负责转义输入.这意味着清理代码是由编写JDBC驱动程序的人编写的,这些人可能知道数据库特定的转义规则的来龙去脉.他们也很可能比你测试手动转义函数更彻底地测试那些逃避规则.
因此,如果您编写preparedStatement.setString(1,name),该方法的实现(同样,由您正在使用的DB的JDBC驱动程序人员编写)可能大致如下:
public void setString(int idx, String value) {
String sanitized = ourPrivateSanitizeMethod(value);
internalSetString(idx, value);
}
(请记住,上面的代码是一个非常粗略的草图;许多JDBC驱动程序实际上处理它的方式完全不同,但原理基本相同.)
另一个问题是myUserInputVar是否已被清理可能是不明显的.请看以下代码段:
private void updateUser(int name, String id) throws SQLException {
myStat.executeUpdate("UPDATE user SET name=" + name + " WHERE id=" + id);
}
这样安全吗?您不知道,因为代码中没有任何内容表明名称是否已被清理.而且你不能只是重新消毒“保持安全”,因为这会改变输入(例如,你好’世界会变成你好’世界).另一方面,UPDATE用户SET名称的准备语句=? WHERE id =?总是安全的,因为PreparedStatement的实现在将值插入?之前会转义输入.
本文标题为:java – 准备语句如何比语句更好地防止SQL注入?
基础教程推荐
- 详谈StringUtils3之StringUtils.isEmpty()和StringUtils.isB的区别 2023-02-11
- Mybatis结果集映射与生命周期详细介绍 2023-06-10
- SpringCloud Gateway中GatewayFilterChain执行流程详解 2023-06-17
- java实现图书检索系统 2022-11-16
- 详解Hibernate注解方式的二级缓存 2023-07-31
- JSP中response.setContentType和response.setCharacterEncoding区别分析 2023-08-03
- Java中的AQS同步队列问题详解 2022-12-07
- Java实现平铺列表(List)互转树形(Tree)结构 2023-03-31
- 基于JAVA和MYSQL数据库实现的学生信息管理系统 2023-11-04
- 如何在Java项目中添加/使用嵌入式SQLite? 2023-11-06