sql注入

百度百科定义:

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

先看测试代码:

数据库:

db.properties程序

1 driver=com.mysql.jdbc.Driver
2 url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
3 username=root
4 password=123456

JdbcUtils.java

 1 public class JdbcUtils {
 2     private static String driver = null;
 3     private static String url = null;
 4     private static String username = null;
 5     private static String password = null;
 6     static {
 7         try {
 8             InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
 9             Properties properties = new Properties();
10             properties.load(in);
11 
12             driver = properties.getProperty("driver");
13             url = properties.getProperty("url");
14             username = properties.getProperty("username");
15             password = properties.getProperty("password");
16 
17             // 驱动只用加载一次
18             Class.forName(driver);
19 
20 
21         } catch (Exception e) {
22             e.printStackTrace();
23         }
24     }
25 
26     // 获取连接
27     public static Connection getConnection() throws SQLException {
28         return DriverManager.getConnection(url, username, password);
29     }
30 
31     // 释放资源
32     public static void release(Connection con, Statement st, ResultSet rs) throws SQLException {
33         if (rs != null) {
34             rs.close();
35         }
36         if (st != null) {
37             st.close();
38         }
39         if (con != null) {
40             con.close();
41         }
42     }
43 
44 
45 }

sql注入.java

 1 public class SQL注入 {
 2     public static void main(String[] args) throws SQLException {
 3 
 4        // login("zhangsan", "123456"); // 正常登录
 5         login("'or ' 1 = 1","123456");
 6     }
 7 
 8     // 登录业务
 9     public static void login(String username, String password) throws SQLException {
10 
11         Connection conn = null;
12         Statement st = null;
13         ResultSet rs = null;
14         try {
15             conn = JdbcUtils.getConnection();
16             st = conn.createStatement();
17             // SQL
18             String sql = "select * from users where `name` = '" + username + "' AND  `password`  = '" + password +"'";
19             rs = st.executeQuery(sql); // 查询完毕返回一个结果集
20             while(rs.next()) {
21                 System.out.println(rs.getString("name"));
22                 System.out.println(rs.getString("password"));
23             }
24         } catch (SQLException e) {
25             e.printStackTrace();
26         } finally {
27             JdbcUtils.release(conn, st, rs);
28         }
29     }
30 }

结果分析:输入一个逻辑上正确的语句,瞒过系统,取出了数据库所有的信息。

 解决方案:使用PrepareStatement,PrepareStatement和statement的本质区别就是可以防止SQL注入,并且效率更高

public class TestInsert {
    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        PreparedStatement st =  null;
        try {
            conn = JdbcUtils.getConnection();
            // 区别,使用?占位符代替参数
            String sql = "insert into users(id, `name`,`password`,`email`,`birthday`) values(?,?,?,?,?)";
            st = conn.prepareStatement(sql);  // 预编译sql,先写sql但是不执行

            // 手动给参数赋值
            st.setInt(1,4);
            st.setString(2,"cxk");
            st.setString(3,"123432");
            st.setString(4,"355657575@qq.com");
            // 注意点: sql.Date 数据库   java.sql.Date()转化为sql的
            // util.Date  JAVA   new Date().getTime() 获得时间戳
            st.setDate(5,new java.sql.Date(new Date().getTime()));
            // 执行,返回受影响行数
            int i = st.executeUpdate();

            if (i < 0) {
                System.out.println("插入成功");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn, st, null);
        }
    }
}
原文地址:https://www.cnblogs.com/YXBLOGXYY/p/14640812.html