SQL注入及防止--传入非法参数 IDEA+JAVA

发布于:2023-01-17 ⋅ 阅读:(536) ⋅ 点赞:(0)

目录

一、什么是SQL注入?

二、SQL注入的原理

1)恶意拼接查询

2)利用注释执行非法命令

3)传入非法参数

4)添加额外条件

三、SQL注入实例--传入非法参数

1.拼接SQL语句方法

2.SQL传参方法

3. 库操作


一、什么是SQL注入?

SQL注入即是指 web应用程序中数据库层的安全漏洞,因为没有对用户输入数据的合法性没有判断或过滤,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的 SQL语句 ,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

二、SQL注入的原理

SQL注入主要有以下4点:

1)恶意拼接查询

SQL语句可以对数据进行增删改查,且使用分号来分隔不同命令。例如:

select * from t_user where id = $id


 其中id是传入的参数,如果传入参数的值为"123;delete from t_user",那么最终执行的查询为:

select * from t_user where id = 123;delete from t_user


如果执行以上语句,则会删除表中的所有数据

2)利用注释执行非法命令

SQL语句中可以插入注释,例如

select conut(*) as 'num' from score where id =$id 

如果version包含了恶意的字符串" '1' or 3 and sleep(500) ",那么最终查询的语句会变为

select conut(*) as 'num' from score where id ='1' or 3 and sleep(500) 


以上恶意查询只是想耗尽系统资源,sleep(500) 将导致 SQL 语句一直运行,保持休眠。如果其中添加了修改、删除数据的恶意指令,那么将会造成更大的破坏。

3)传入非法参数

SQL 语句中传入的字符串参数是用单引号引起来的,如果字符串本身包含单引号而没有被处理,那么可能会篡改原本 SQL 语句的作用。 例如:

select * from t_user where name = $name

如果 name 传入参数值为 R'rong,那么最终的查询语句会变为:

select * from t_user where name = 'R'rong'

一般情况下,以上语句会执行出错,这样的语句风险还比较小。如果携带了更多更复杂的语句,可能会恶意产生 SQL 语句,并且以一种不正当的方式运行。

4)添加额外条件

在 SQL 语句中添加一些额外条件,以此来改变执行行为。条件一般为真值表达式。例如:

update t_user set pwd='$pwd' where id=$id


如果 user_id 被传入恶意的字符串“1 or true”,那么最终的 SQL 语句会变为:

update t_user set pwd='123' where id='1' OR true


如果执行以上语句,将更改所有用户的密码为123

三、SQL注入实例--传入非法参数

简单的模仿黑客不需要输入用户名密码进行的登录操作。

以下实例我使用本机端口的jdbc数据库,用户名和密码均是root。

1.拼接SQL语句方法

如果使用的是拼接SQL语句方法进行登录操作,输入任意的用户名+' or '1'='1密码,都可以直接登录成功。

Scanner sc = new Scanner(System.in);
        System.out.println("请输入登录的用户名:");
        String name = sc.nextLine();
        System.out.println("请输入登录的密码:");
        String pwd = sc.nextLine();
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "root");
            PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user where name='" + name + "' and pwd='" + pwd + "'");
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                System.out.println("登录成功!");
            } else {
                System.out.println("登录失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

2.SQL传参方法

如果使用的是SQL传参方法进行登录操作,输入任意的用户名+' or '1'='1密码,不能登录成功。

 Scanner sc = new Scanner(System.in);
        System.out.println("请输入登录的用户名:");
        String name = sc.nextLine();
        System.out.println("请输入登录的密码:");
        String pwd = sc.nextLine();
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "root");
            PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user where name= ? and pwd=? +");
            preparedStatement.setString(1,name);
            preparedStatement.setString(2,pwd);
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                System.out.println("登录成功!");
            } else {
                System.out.println("登录失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } 

3. 库操作

当我们将如图代码输入:

select * from t_user where name='addaxgguhuc' and pwd= '' or '1'='1';

不论我们是否知道用户名和密码,都可以直接查出数据库中的信息。

 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到