*JDBC是Java对数据库进行操作的一个桥梁.
借助数据库提供的数据驱动, 加上要操作的数据库语言,
执行数据库语句之后就可以对数据库里面的记录进行增 删 改 查(crud)操作了.*
案例一: sql注入,欺骗服务器执行恶意的SQL命令
1.先写一个工具类MyJdbcUtils,封装两个方法:
(1)封装连接到数据库的方法getConnection();
// 加载配置文件
static {
Properties p = new Properties();
InputStream is;
try {
// 获取输入流路径
is = new FileInputStream("src/db.properties");
// 用Properties对象加载输入流
p.load(is);
//驱动路径
drivername = p.getProperty("drivername");
//数据库路径
url = p.getProperty("url");
//数据库用户名
username = p.getProperty("username");
//数据库密码
password = p.getProperty("password");
}catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws Exception{
//加载驱动
Class.forName(drivername);
//连接数据库
Connection con=DriverManager.getConnection(url, username, password);
return con;
}
(2)封装释放资源的方法
releaseSource();
public static void releaseSource(ResultSet rs,Statement st,Connection con){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs=null;
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
st=null;
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
con=null;
}
}
2.然后通过下面这个测试类实现sql注入
这种编写sql语句的方法给了sql注入可乘之机!!!!!
public class Test1_sql_IllegalLogin {
/**
* sql的恶意注入案例
* 模拟登陆
*/
public static void main(String[] args) {
// 键盘录入用户名和密码
Scanner sc=new Scanner(System.in);
System.out.println("username:");
String username = sc.nextLine().trim();
System.out.println("password:");
String password = sc.nextLine().trim();
login(username,password);
}
private static void login(String username,String password) {
Connection con=null;
Statement st=null;
ResultSet rs=null;
//查询数据库,获取用户名和密码
try {
con = MyJDBC_util_Illegal.getConnection();
//编写sql代码
String sql="select * from Person where username='"+username+"'and password='"+password+"'";
//执行sql代码
ps = con.createStatement();
rs = ps.executeQuery(sql); //获取结果集
if(rs.next()){
System.out.println("welcome!"); //登陆成功
}else{
System.out.println("Login failed"); //登陆失败
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
MyJDBC_util_Illegal.releaseSource(rs, st, con);
}
}
}
运行会出现如下结果:
是不是很带劲??? 不输入密码也可以登录进去!! 盗号必备技能!! 6666~
然而… 怎么防止恶意注入呢??
Tips:
*在执行sql之前采用预编译,设置sql语句里面的参数.
*sql语句里面参数的值用占位符 ? 代替,可以达到固定格式的作用
案例二: 防止sql注入
1.将变量Statement st 修改为PreparedStatement ps; 用来预编译sql语句!
2.编写sql语句时用占位符 ? 代替字段的值, 这样就可以固定sql语句的格式了!
public class Test2_sql_PreStatementLogin {
/**
* sql注入的防止
* 模拟登陆
*/
public static void main(String[] args) {
// 键盘录入用户名和密码
Scanner sc=new Scanner(System.in);
System.out.println("username:");
String username = sc.nextLine().trim();
System.out.println("password:");
String password = sc.nextLine().trim();
login(username,password);
}
private static void login(String username,String password) {
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
//查询数据库,获取用户名和密码
try {
con = MyJDBC_util_Login.getConnection();
String sql="select * from Person where username=? and password=?";
//预编译sql代码
ps = con.prepareStatement(sql);
//设置参数
ps.setString(1, username);
ps.setString(2, password);
//执行sql代码
rs = ps.executeQuery(); //获取结果集
if(rs.next()){
System.out.println("welcome!"); //登陆成功
}else{
System.out.println("Login failed"); //登陆失败
}
} catch (Exception e) {
e.printStackTrace();
}finally{
MyJDBC_util_Login.releaseSource(rs, ps, con);
}
}
}
关键是固定了编写sql语句的格式, 使那些恶意输入的语句再也嚣张不起来了!!! 哈哈!~~
第一篇博客,想想还是有点小激动的~~~ 吼吼吼….