zoukankan      html  css  js  c++  java
  • SQL注入及解决方案

    SQL注入及解决方案

    SQL注入

    如果说你要实现一个登录的业务, 需要username和password来验证登录

    当接收到用户输入的username和password时, 我们假设使用字符串拼接的形式注入SQL语句

    例如, 我们的SQL语句时这样的 (假设uname时用户输入的用户名, pwd是密码)

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

    我如果输入用户名: tom'#' 密码随便输入或者不输入, 那么你的SQL语句就变成了这样:

    select * from user where username = 'tom'#'' and password = '你输入的密码'
    

    可见 # 号后面的password条件被当成了SQL中的注释, 并未被执行

    或者输入用户名为: tom' or '1=1 , 密码不输入或者随便输入, SQL如下:

    select * from user from username = 'tom' or '1=1' and password = '你输入的密码'
    

    有了or 自然只要username = 'tom' 成立, 后面的也不会起作用

    解决方案

    使用prepareStatement 来代替原有的 Statement

    这里依然使用了JDBC的 工具类 来获取Connection连接对象和关闭操作

    Connection conn = null;
    // Statement stat = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    try {
        // 注册驱动并连接
        conn = JdbcUtil.getConn();
        // 获取传输器, 执行sql并返回结果
        String sql = "select * from user where username = ? and password = ?";
        ps = conn.prepareStatement(sql);
        ps.setString(1, user);
        ps.setString(2, pwd);
        rs = ps.executeQuery();
        System.out.println(ps);
        // 处理结果 检查是否允许登录
        if (rs.next()) { // true -- 有数据
            System.out.println("登录成功! ");
        } else {
            System.out.println("登录失败! 用户名或密码错误");
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(conn, ps, rs);
    }
    

    注意, 调用setString() 或者 setInt() , setDouble() 等方法的时候, 第一个参数是从1开始的, 表示第几个问号

    这样就解决了!!!

    插入数据案例

    Connection conn = null;
    PreparedStatement ps = null;
    try {
        conn = JdbcUtil.getConn();
        String sql = "insert into user value(null, ?, ?)";
        ps = conn.prepareStatement(sql);
        ps.setString(1, "孙尚香");
        ps.setString(2, "123456");
        int rows = ps.executeUpdate();
        System.out.println("影响行数: " + rows);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(conn, ps, null);
    }
    

    查询数据案例

    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    try {
        conn = JdbcUtil.getConn();
        String sql = "select * from user";
        ps = conn.prepareStatement(sql);
        rs = ps.executeQuery();
        while (rs.next()) {
            System.out.print(rs.getInt("id") + ", ");
            System.out.print(rs.getString("username") + ", ");
            System.out.print(rs.getString("password") + "
    ");
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(conn, ps, rs);
    }
    
  • 相关阅读:
    Echarts——一个简单的嵌套饼图
    Gephi——使用map of countries和Geo Layout实现包含地理坐标的数据可视化
    PMP知识点(五)——资源管理表示方法
    Python——LOL官方商城皮肤信息爬取(一次练手)
    Python——一个简单的进度条的实现
    Python——阶段总结(一)
    PMP知识点(六)——项目经理权利类型
    PMP知识点(五)——配置管理
    Python——使用高德API获取指定城指定类别POI并实现XLSX文件合并
    PMP知识点(一)——风险登记册
  • 原文地址:https://www.cnblogs.com/zpKang/p/13033347.html
Copyright © 2011-2022 走看看