JDBC的复习(三):Sql注入问题和解决

6 篇文章 0 订阅

JDBC的复习(三):Sql注入问题和解决

Sql注入问题

image-20220228125529682

用户名:
dasa
密码:
dasa' or '1' = '1
登陆成功!

根本原因:

用户输入的信息中含有sql语句的关键字,并且这些关键字参与了sql语句的编译过程,导致原来的sql语句意思被扭曲,进而达到sql注入。

image-20220228130506138

解决Sql注入

  • 只要用户提供的信息不参与SQl的编译过程,就可以解决该问题
  • 即使用户输入的语句中含有SQL语句的关键字,到那时没有参与编译,不起作用。
  • 使用PrePareStatement进行sql语句框架的预编译。
 /**
     * 登陆函数,判断登陆是否成功
     * @param userLoginInfo
     * @return 返回登陆是否成功
     */
    private static boolean Login(Map<String, String> userLoginInfo) {
        boolean flag = false;

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        String userName = userLoginInfo.get("useName");
        String passWord = userLoginInfo.get("passWord");

        try {
            //1. 注册驱动

            Class.forName("com.mysql.jdbc.Driver");
            //2. 获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?characterEncoding=UTF8&useSSL=false","root","001204");
            //3. 获取操作对象
            //SQL语句的框架
            String sql = "select * from userinfo where userName = ? and passWord = ?";
            ps = conn.prepareStatement(sql);
            //占位符,第一?下标是1,第二个?下表是标记
            ps.setString(1,userName);
            ps.setString(2,passWord);
            //4. 执行sql语句
            rs = ps.executeQuery();

            //5. 处理查询结果集合
            if(rs.next()){
                flag = true;
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {

            try {
                //释放资源
                if(rs!=null){
                    rs.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            try {
                //释放资源
                if(ps!=null){
                    ps.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            try {
                //释放资源
                if(conn!=null){
                    conn.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        }

        return flag;
    }

image-20220228150235727

Statement和PrePareStatement的对比

  • Statement存在sql注入问题,PrePareStatement解决了这个问题
  • Statement是编译一次执行一次,PrePareStatement是编译一次执行N次,相比较而言,效率更高
  • PrePareStatement会在编译阶段做类型的安全性检查

Statement的作用演示

package com.bjpowernode.jdb;

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

import static java.lang.System.exit;

/**
 * @author 31200
 */
public class JdbcTest08 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stat = null;
        ResultSet rs = null;
        while(true){
            System.out.println("请输入desc表示降序或者asc表示升序:");
            Scanner scanner = new Scanner(System.in);
            //获取到输入的信息
            String character = scanner.nextLine();
            if(!("desc".equals(character) || "asc".equals(character))){
                System.out.println("输入有误区,请重新输入!!!");
                continue;
            }

            try {
                //1. 注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                //2. 获取连接
                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?characterEncoding=UTF8&useSSL=false","root","001204");
                //3. 获取数据库操作对象
                stat = conn.createStatement();
                //4. 执行sql语句
                String sql = "select ename from emp order by ename " + character;
                rs = stat.executeQuery(sql);
                //5. 遍历结果集
                System.out.println("-------------------------------");
                while(rs.next()){
                    String ename = rs.getString("ename");
                    System.out.println(ename);
                }
                exit(0);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                //释放资源
                try {
                    if(rs!=null){
                        rs.close();
                    }
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
                try {
                    if(stat!=null){
                        stat.close();
                    }
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
                try {
                    if(conn!=null){
                        conn.close();
                    }
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
}

image-20220228155645233

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值