SQ注入
就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,以达到欺骗服务器执行恶意的SQL命令
SQL注入产生原因
SQL注入的攻击行为可描述为通过在用户可控参数中注入SQL语法,破坏原有SQL结构,达到编写程序时的攻击行为。其成因可以归结为以下两个原因所造成的:
1.在处理应用程序和数据库交互时,使用字符串拼接的方式构造SQL语句
2.未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中
SQL注入攻击方式
SQL注入攻击方式根据应用程序处理数据库返回内容的不同分为三种:
1.可显示注入:直接在当前页面上获取所需要的内容
2.报错注入:数据库查询返回结果没有在页面显示,在应用程序中打印报错信息,通过构造数据库报错语句,从报错信息中获取所需要的内容
3.盲注:数据库查询返回结果不能页面中获取,通过数据库逻辑或使数据库库执行延时等方法获取所需要的内容
import java.sql.*;
public class TestJDBC {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
Statement stmt = null;
ResultSet rs = null;
String sql="";
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
//采用拼接,没有经过特殊处理,很容易SQL注入
//sql ="secelt * from student while name='"+username+"'and psw='"+userpassword+"'" ";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
rs.close();
stmt.close();
conn.close();
}catch (Exception e) {
}{
}
}
}
}
1.经过采用预编译语句集,防止SQL注入
sql= "select * from student where username=? and password=?;
PreparedStatement ps= conn.prepareStatement(sql);
ps.setString(1, userName);
ps.setString(2, password);
ResultSet rs = ps.executeQuery();
2.采用正则表达式单引号(')、分号(;) 、注释符号(--)替换来防止SQL注入
public static String TransactSQLInjection(String sql) {
return sql.replaceAll(".*([';]+|(--)+).*", " ");
}
sql ="secelt * from student while name='"+username+"'and
psw='"+userpassword+"'" ";
userName=TransactSQLInjection(userName);
password=TransactSQLInjection(password);
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
3.使用Hibernate框架的SQL注入防范(Hibernate的好处是1.安全2.提高开发效率)通过参数化的方式来防范SQL注入,不采用拼接方式
String queryStr = “from student where username=:username ”+”password=:password”;
List result = session.createQuery(queryStr).setString("username",username).setString("password", password).list();
mybatis框架作为一款半自动化的持久层框架,Mybatis的sql是一个具有“输入+输出”功能,类似于函数的结构
<insert id="addStudent" parameterType="Student">
insert into Student ( name ) values (#{name})
</insert>
parameterType表示输入的参数类型
mybatis启用了预编译功能,在sql执行前,会先将上面的sql发送给数据库进行编译,执行时,直接使用编译好的sql
mybatis接口中的函数标签的SQL语句,标注中的SQL语句通过'#'表示占位符,内部实现是参数化预处理
@Insert(" insert into Student ( name ) values (#{name}) ")
public int add(Student student);