dedecms手机网站模板安装教程绵阳网站
1 原理
没有正确的对用户的输入进行检查,将用户的输入以拼接的方式带入到SQL语句中,导致SQL注入。
2 产生SQL注入的原因
2.1 JDBC拼接不当造成SQL注入
前置知识:
- JDBC执行SQL语句的两种方式:
 
- PrepareStatement:会对sql语句进行预编译,效率和安全性更好。支持使用
 ?对变量位进行占位。- Statement:每次执行时都需要编译
 
-  
典型的错误拼接方式:
String sql="select * from user where id=" + req.getParameter("id"); Statement st = con.createStatement(); ResultSet rs = st.executeQuery(sql); -  
正确的拼接方式:使用占位符
String sql="select * from user where id=?"; PreparedStatement pstt = con.PreparedStatement(sql); pstt.setInt(1,Integer.parseInt(req.getParameter("id"))); ResultSet rs = pstt.executeQuery(); -  
防御:使用
PreparedStatement,且不要把用户输入的东西拼到SQL语句里。 
2.2 框架使用不当造成sql注入
① MyBatis框架
SQL传参的两种方式:
#{parameter}、${parameter}
-  
思想:将SQL语句编入到配置文件中,避免SQL语句在Java程序中大量出现,方便后续对SQL语句的修改与配置。
 -  
#与$的区别-  
#{}:可以试用?进行预编译,安全,推荐使用。eg:如下代码
<select id="getUsername" resultType="com.zlong.bean.User">select id,name,age from user where name = #{name} </select>其中将
#{name}先使用?占位进行预编译,然后再传参,不存在sql注入的问题。 -  
${}:直接拼接到语句中,不安全eg:如下代码
<select id="getUsername" resultType="com.zlong.bean.User">select id,name,age from user where name = ${name} </select>该代码直接将用户的值拼接到sql语句中,可以触发恶意的代码。
 
 -  
 
② Hibernate框架
Hibernate框架是持久性API,因此是对持久化类的对象进行操作,而不是直接对数据库,语句由Hibernate进行解析。它是将JAVA类映射到数据库表中,从JAVA数据类型映射到SQL数据类型。直接拼接可能会导致注入漏洞。
- 使用以下HQL参数绑定的方法(预编译)避免注入漏洞
 
-  
位置参数
String parameter = "z1ng"; Query<User> query = session.createQuery("from com.z1ng.bean.User where name = ?1",User.class); query.setParameter(1,parameter); -  
命名参数
String parameter = "z1ng"; Query<User> query = session.createQuery("from com.z1ng.bean.User where name = :name",User.class); query.setParameter("name",parameter); -  
命名参数列表
List<string> names = Arrays.asList("z1ng","z2ng"); Query<User> query = session.createQuery("from com.z1ng.bean.User where names in (:names)",User.class); query.setParameter("names",names); -  
类实例(Bean)
user1.setName("z1ng"); Query<User> query = session.createQuery("from com.z1ng.bean.User where name = :name",User.class); query.properties(user1); 
- 参数绑定的方法构造SQL语句(Hibernate支持原生SQL语句执行)
 
-  
正确的参数绑定方法
Query<User> query = session.createNativeQuery("select * from user where name = :name"); query.setParameter("name",parameter); -  
错误的拼接方法
Query<User> query = session.createNativeQuery("select * from user where name = '"+parameter="'"); 
2.3 防御不当造成SQL注入
预防SQL注入漏洞一般正确使用预编译就可以,但是存在特殊情况不可以使用预编译:sql注入的order by后的参数赋值就不能使用预编译进行防止SQL注入。故除预编译之外,需要对用户的输入进行严格的过滤,包括参数类型,参数格式。
