文章目录
JDBC中 sql注入问题及解决
一、sql注入问题
SQL作为字符串通过API传入给数据库,数据库将查询的结果返回,数据库自身是无法分辨传入的SQL是合法的还是不合法的,它完全信任传入的数据,如果传入的SQL语句被恶意用户控制或者篡改,将导致数据库以当前调用者的身份执行预期之外的命令并且返回结果,导致安全问题。
1、sql注入的影响:
- 可读取数据库中的库和表
- 可执行系统命令
- 可以任意修改和删除任意文件
- 可以安装木马后门
2、jdbc中sql注入的例子:
//模拟登录事务(正常查询)
public class SqlInjection {
public static void main(String[] args) {
login("zhansan","123456");
}
public static void login(String name,String password){
JdbcUtil jdbcUtil = new JdbcUtil();
Connection conn = jdbcUtil.getConnection();
Statement sta =null;
ResultSet rs =null;
try {
sta = conn.createStatement();
String sql="select * from users where `NAME`='"+name+"'and `PASSWORD`='"+password+"'";
rs = sta.executeQuery(sql);
while (rs.next()){
System.out.println(rs.getString("name"));
System.out.println(rs.getString("password"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
jdbcUtil.release(conn,sta,rs);
}
}
}
//非正常登录(sql注入)
public class SqlInjection {
public static void main(String[] args) {
login(" 'or '1=1","'or'1=1"); //通过or恒等式窃取你的全部用户数据
}
public static void login(String name,String password){
JdbcUtil jdbcUtil = new JdbcUtil();
Connection conn = jdbcUtil.getConnection();
Statement sta =null;
ResultSet rs =null;
try {
sta = conn.createStatement();
String sql="select * from users where `NAME`='"+name+"'and `PASSWORD`='"+password+"'";
rs = sta.executeQuery(sql);
while (rs.next()){
System.out.println(rs.getString("name"));
System.out.println(rs.getString("password"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
jdbcUtil.release(conn,sta,rs);
}
}
}
二、PreparedStatement对象
1、PreparedStatement对象与Statement对象的区别:
-
PreparedStatement继承Statement,都是接口
-
PreparedStatement对象可以防止sql注入,比Statement安全
-
PreparedStatement效率更高,执行sql语句快
-
PreparedStatement 防止sql注入的本质:将传递进来的参数当做字符;假设其中存在转义字符,比如’会被直接转义
//使用PreparedStatement对象防止sql注入
public class PstaSelect {
public static void main(String[] args) {
login("zhansan","123456");//sql注入不管用
}
public static void login(String name,String password){
JdbcUtil jdbcUtil = new JdbcUtil();
PreparedStatement psta =null;
ResultSet rs =null;
Connection conn = jdbcUtil.getConnection();
try {
String sql = "select * from users where `NAME`=? and `PASSWORD`=?";
//PreparedStatement 防止sql注入的本质:将传递进来的参数当做字符
//假设其中存在转义字符,比如'会被直接转义
psta = conn.prepareStatement(sql);//预编译
//传递参数
psta.setString(1,name);
psta.setString(2,password);
rs = psta.executeQuery();//执行
while(rs.next()){
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("password"));
System.out.println(rs.getString("email"));
System.out.println(rs.getString("birthday"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
jdbcUtil.release(conn,psta,rs);
}
}
}