什么是SQL注入漏洞

SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。
本质:是利用拼接字符串的原理,注入一些特殊的非法字符和关键字把系统原来逻辑正确的sql语义给改变了
例如登录案例,参见下方代码模拟

代码模拟SQL注入问题

@Test
public void testLogin() throws  Exception {
    //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
    String url = "jdbc:mysql:///db1?useSSL=false";
    String username = "root";
    String password = "1234";
    Connection conn = DriverManager.getConnection(url, username, password);

    // 接收用户输入 用户名和密码
    String name = "sjdljfld";
    String pwd = "' or '1' = '1";
    String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
    // 获取stmt对象
    Statement stmt = conn.createStatement();
    // 执行sql
    ResultSet rs = stmt.executeQuery(sql);
    // 判断登录是否成功
    if(rs.next()){
        System.out.println("登录成功~");
    }else{
        System.out.println("登录失败~");
    }

    //7. 释放资源
    rs.close();
    stmt.close();
    conn.close();
}

上面代码是将用户名和密码拼接到sql语句中,拼接后的sql语句如下

select * from tb_user where username = 'sjdljfld' and password = ''or '1' = '1'

从上面语句可以看出条件 username = 'sjdljfld' and password = '' 不管是否满足,而 or 后面的 '1' = '1' 是始终满足的,最终条件是成立的,就可以正常的进行登陆了。

如何解决SQL注入漏洞

JDBC编写代码时使用PreparedStatement完成SQL语句的传入。使用占位符?代替要传入的参数
原理是转译,将''变成\'这样的文本字符无论怎么转。你传入的参数都只能被当作一个参数。而不是sq语句的一部分

针对这个登录案例,B站弹幕上有一个朋友:采用直接根据用户名查出密码然后再对比的方式进行规避。
其实后面直接使用框架基本不会出现这个问题。更多还是学网络安全吧。