栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SQL注入问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SQL注入问题

先准备一个user表

插入两条数据

CREATE TABLE USER(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAr(32),
    PASSWORD VARCHAr(32)
    );
    
INSERT INTO USER VALUES(NULL,'zhangsan','123'),(NULL,'lisi','abc');

使用JDBC操作数据库

注意连接数据库时,要把代码中的数据库名以及密码改成自己的

import java.sql.*;
import java.util.Scanner;

public class JDBCDemo4 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        Statement statement=null;
        Connection con=null;
        ResultSet rs=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url="jdbc:mysql://localhost:3306/db2?characterEncoding=utf8";
            con= DriverManager.getConnection(url,"root","root");
            statement=con.createStatement();
            System.out.println("请输入用户名:");
            String username=sc.nextLine();
            System.out.println("请输入密码:");
            String password=sc.nextLine();
            String sql="select * from user where username='"+username+"' and password='"+password+"'";
            rs=statement.executeQuery(sql);
            if(rs.next())   // 有下一个就说明查询到数据了
                System.out.println("登录成功!");
            else
                System.out.println("密码或用户名错误!");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        // 释放资源
        finally{
            if(rs != null) {
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if(statement != null) {
                try {
                    statement.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(con != null) {
                try {
                    con.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
}

  

 这两个运行结果都没有问题

接下来请看看第三个运行示例结果:

这里输入的密码明显是错的,但是居然登录成功了 !!!

到底是为什么呢?

返回去看看sql查询语句

String sql="select * from user where username='"+username+"' and password='"+password+"'";

 它是由字符串拼接而成的

所以第三张图的输入组成的sql查询语句为:

select * from user where username='zhangsan' and password='1' or 'a'='a'

 问题出现在这里

or 'a'='a'

 'a'='a'是一定成立的,并且使用了or连接,因此该条件不管什么时候都是成立的。

这里使用java的PreparedStatement解决该问题

import java.sql.*;
import java.util.Scanner;

public class JDBCDemo4 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        PreparedStatement ps=null;
        Connection con=null;
        ResultSet rs=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url="jdbc:mysql://localhost:3306/db2?characterEncoding=utf8";
            con= DriverManager.getConnection(url,"root","root");
            System.out.println("请输入用户名:");
            String username=sc.nextLine();
            System.out.println("请输入密码:");
            String password=sc.nextLine();
            String sql="select * from user where username=? and password=?";
            ps=con.prepareStatement(sql);
            ps.setString(1,username);
            ps.setString(2,password);
            rs=ps.executeQuery();
            if(rs.next())   // 有下一个就说明查询到数据了
                System.out.println("登录成功!");
            else
                System.out.println("密码或用户名错误!");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        // 释放资源
        finally{
            if(rs != null) {
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if(ps != null) {
                try {
                    ps.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(con != null) {
                try {
                    con.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
}

修改代码后,再次运行: 

 到这里输入'1' or 'a'='a就会登录失败了。

PreparedStatement使用的是预编译方式,会把sql语句空缺部分使用'?'占位了,然后进行预编译,sql语句就不是通过字符串拼接得来的了,以此解决SQL注入问题。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/356960.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号