博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java学习笔记38(sql注入攻击及解决方法)
阅读量:4674 次
发布时间:2019-06-09

本文共 3911 字,大约阅读时间需要 13 分钟。

上一篇我们写了jdbc工具类:JDBCUtils ,在这里我们使用该工具类来连接数据库,

在之前我们使用 Statement接口下的executeQuery(sql)方法来执行搜索语句,但是这个接口并不安全,容易被注入攻击,注入攻击示例:

首先我们需要一个存放登录用户名密码的表:

use qy97;create table login(  id int primary key auto_increment,  sname varchar(50),  pwd varchar(50));insert into login values(1,'zhangsan','111'),(2,'lisi','123');

然后我们写代码实现登陆:

package com.zs.Demo;import JDBCUtils.JDBCUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Scanner;public class SQLZhuRu {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        System.out.println("请输入用户名:");        String name = sc.nextLine();        System.out.println("请输入密码:");        String pwd = sc.nextLine();        login(name,pwd);    }    private static void login(String name, String pwd) {        Connection conn = JDBCUtils.getConnection();        String sql = "select * from login where sname='"+name+"'and pwd='"+pwd+"';";        System.out.println(sql);        Statement stat = null;        ResultSet rs=null;        try {            stat = conn.createStatement();            rs = stat.executeQuery(sql);            if (rs.next()) {                System.out.println("登陆成功,欢迎" + rs.getString("sname"));            } else {                System.out.println("登录失败!!");            }        } catch (SQLException e) {            e.printStackTrace();        }        JDBCUtils.close(conn,stat,rs);    }}

运行结果如下:

输入账号密码,然后在数据库中搜索,搜索到数据则登录成功,否则登录失败:

可是,当我们这样输入时,也能登陆成功:

从上面语句可以看出,执行的sql与语句是:select * from login where sname='lisi'and pwd='789 'or'1=1';

1=1是恒成立的,or 只要两边有一个为true 则为 true  ,所以登录成功,这是一个最简单的注入攻击,

解决方法:使用prepareStatement接口,以上一个例子为基础做修改

package com.zs.Demo;import JDBCUtils.JDBCUtils;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.Scanner;public class PerpareStatementDemo {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        System.out.println("请输入用户名:");        String name = sc.nextLine();        System.out.println("请输入密码:");        String pwd = sc.nextLine();        try {            login(name,pwd);        } catch (Exception e) {            e.printStackTrace();        }    }    //传递变量name pwd给方法    private static void login(String name, String pwd) throws Exception {        Connection conn = JDBCUtils.getConnection();//        设置?占位置,将查询的参数用?来替换        String sql="select * from login where sname=? and pwd=?";        PreparedStatement pre = conn.prepareStatement(sql);//        setObject方法来设置占位的?的值        pre.setObject(1,name);//设置第一个?的值为变量name        pre.setObject(2,pwd);//设置第二个?的值为变量pwd        ResultSet rs = pre.executeQuery();        if (rs.next()) {            System.out.println("登陆成功");        } else {            System.out.println("登录失败");        }        JDBCUtils.close(conn, pre, rs);    }}

运行结果:

 

可以看出,在不改变sql语句的情况下将?替换为变量的值,当注入攻击时:

可以看出来这个接口更加安全,所以建议使用这个接口来实现增删改查;关于PrepareStatement接口:(官方文档)

  PrepareStatement接口:

    表示预编译的SQL语句的对象。

    SQL语句已预编译并存储在PreparedStatement对象中。 然后可以使用该对象多次有效地执行此语句。

    注意:setter方法( setShortsetString用于设置IN参数值必须指定与所定义的SQL类型的输入参数的兼容的类型,等等)。 例如,如果IN参数具有SQL类型INTEGER ,   则应使用方法setInt

使用PrepareStatemnet接口实现数据库的更新:

package com.zs.Demo;import JDBCUtils.JDBCUtils;import java.sql.Connection;import java.sql.PreparedStatement;public class PrepareStatementDemo2 {    public static void main(String[] args) {        Connection conn = JDBCUtils.getConnection();        String sql="update login set sname = ? where id=?;";        PreparedStatement pst =null;        try {            pst = conn.prepareStatement(sql);            pst.setObject(1, "dijia");            pst.setObject(2,1);            pst.executeUpdate();        } catch (Exception e) {            e.printStackTrace();        }finally {            JDBCUtils.close(conn, pst);        }    }}

 

转载于:https://www.cnblogs.com/Zs-book1/p/10638578.html

你可能感兴趣的文章
JS兼容性问题
查看>>
Java实现Oracle导出数据到Excel
查看>>
Python相关网站(持续更新)
查看>>
EventLog实现事件日志操作
查看>>
VS2010上连接SQLite数据库
查看>>
Oracle数据库安装图文操作步骤
查看>>
贪心算法的简单理解
查看>>
Linux性能检测常用的10个基本命令
查看>>
Mac上传代码到Github
查看>>
day80 django模版学习
查看>>
Java实现注册邮箱激活验证
查看>>
Windows Phone 7 Belling‘s课堂(一) 磁贴的学习
查看>>
WPF 位置转化和动画
查看>>
【log4net】配置文件
查看>>
网易2017春招笔试真题编程题集合
查看>>
玩一下易语言 "和"字有多种读音,注定了它的重要性!!
查看>>
Python中的单例模式的几种实现方式的及优化
查看>>
【转】hadoop机架感知
查看>>
Oracle、DB2、SQLSERVER、Mysql、Access分页SQL语句梳理
查看>>
UVa 10806 Dijkstra,Dijkstra(最小费用最大流)
查看>>