sql注入-预编译如何解决sql注入?

3,464 阅读1分钟

拼接sql

gzh' or '1=1

预编译

sql //参数使用?代替,作为占位符

设置参数(1,id)


示例

// 近似的 JDBC 代码,非 MyBatis 代码...
String selectPerson = "SELECT * FROM PERSON WHERE ID=?";

PreparedStatement ps = conn.prepareStatement(selectPerson);

ps.setInt(1,id); //设置什么类型的参数的时候,可以验证参数的数据类型是否匹配。//不是这个原因?因为如果是字符串类型,gzh'  or '1=1这个也还是一个字符串,这个时候明显验证不了数据类型。所以一定是因为其他的更本质的原因。那本质原因是什么?

示例2
delete user //删除表数据

本质原因

没有预编译,拼接的值如果包含sql关键字,那么就是作为关键字处理。比如,or。

如果是预编译,参数的值就是作为值,哪怕包含了sql关键字,仍然是作为值。比如,gzh' or '1=1这个是作为一个值来匹配数据库里的数据。

预编译的优点

两个
1.防止sql注入
2.sql复用

Mybatis

有两个方法
1.#{实体类字段} //最佳实践。因为是预编译,防止sql注入。
2.${实体类字段} //基本上很少使用

参考

www.zhihu.com/question/52…
segmentfault.com/a/119000000…