sql注入攻擊和PreparedStatement有效防止sql注入攻擊
阿新 • • 發佈:2018-11-17
【1】sql注入攻擊:
/** * SQL 注入. */ @Test public void testSQLInjection() { String username = "a' OR PASSWORD = "; String password = " OR '1'='1"; String sql = "SELECT * FROM user_tbl WHERE user_name = '" + username + "' AND " + "password = '" + password + "'"; // sql注入攻擊使用的sql: SELECT * FROM user_tbl WHERE user_name = 'a' OR PASSWORD = ' AND password = ' OR '1'='1' System.out.println(sql); Connection connection = null; Statement statement = null; ResultSet resultSet = null; try { connection = JdbcUtils.getConnection(); statement = connection.createStatement(); resultSet = statement.executeQuery(sql); if (resultSet.next()) { System.out.println("登入成功!"); } else { System.out.println("使用者名稱和密碼不匹配或使用者名稱不存在. "); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.closeStatAndConnAndResultSet(statement, connection, resultSet); } }
【2】PreparedStatement 有效防止sql注入攻擊
/** * 使用 PreparedStatement 將有效的解決 SQL 注入問題. */ @Test public void testSQLInjection2() { String username = "a' OR PASSWORD = "; String password = " OR '1'='1"; String sql = "SELECT * FROM user_tbl WHERE user_name = ? " + "AND password = ?"; Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { connection = JdbcUtils.getConnection(); preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, username); preparedStatement.setString(2, password); resultSet = preparedStatement.executeQuery(); // 這裡查詢失敗 if (resultSet.next()) { System.out.println("登入成功!"); } else { System.out.println("使用者名稱和密碼不匹配或使用者名稱不存在. "); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.closeStatAndConnAndResultSet(preparedStatement, connection, resultSet); } }
【3】程式碼補充:jdbc工具類
/** * 操作jdbc的工具類-封裝了一些工具方法 * @author pacoson */ public class JdbcUtils { /** * 通用的更新方法:insert, update, delete * 版本1 * @param sql */ public static void updateV2ByPreparedStatement(String sql, Object... objs) { Connection conn = null; PreparedStatement stat = null; try { // 1.獲取資料庫連線 conn = JdbcUtils.getConnection(); // 4.執行插入 // 4.1 獲取操作sql語句的statement物件; // 呼叫Connection的 createStatement() 方法來獲取 stat = conn.prepareStatement(sql); int i = 1; for (Object obj : objs) { stat.setObject(i++, obj); } System.out.println("連線=" + conn + ",語句 = " + stat); // 4.2 呼叫statement物件的 executeUpdate(sql) 執行sql語句進行插入 int updateRows = stat.executeUpdate(); System.out.println("更新記錄行數:" + updateRows); } catch(Exception e) { e.printStackTrace(); } finally { JdbcUtils.closeStatAndConn(stat, conn); } } /** * 通用的更新方法:insert, update, delete * 版本1 * @param sql */ public static void updateV1(String sql) { Connection conn = null; Statement stat = null; try { // 1.獲取資料庫連線 conn = JdbcUtils.getConnection(); // 4.執行插入 // 4.1 獲取操作sql語句的statement物件; // 呼叫Connection的 createStatement() 方法來獲取 stat = conn.createStatement(); System.out.println("連線=" + conn + ",語句 = " + stat); // 4.2 呼叫statement物件的 executeUpdate(sql) 執行sql語句進行插入 int updateRows = stat.executeUpdate(sql); System.out.println("更新記錄行數:" + updateRows); } catch(Exception e) { e.printStackTrace(); } finally { JdbcUtils.closeStatAndConn(stat, conn); } } /** * 獲取連線的方法。 * 通過讀取配置檔案從資料庫伺服器獲取一個連線 * @return * @throws Exception */ public static Connection getConnection() throws Exception { // 讀取類路徑下的 jdbc.properties 檔案並將其封裝到 Properties中: InputStream in = JdbcTest01.class.getClassLoader().getResourceAsStream("jdbc.properties"); Properties props = new Properties(); props.load(in); /* 通過反射獲取驅動器Driver */ Driver driver = (Driver) Class.forName(props.getProperty("driver")).newInstance(); /* 獲取資料庫連線 */ Connection conn = driver.connect(props.getProperty("url"), props); return conn; } /** * 關閉資料庫語句 statement 和 資料庫連線 conn 和 結果集 ResultSet * @param stat * @param conn */ public static void closeStatAndConnAndResultSet(Statement stat, Connection conn, ResultSet rs) { if (null != rs) { try { rs.close(); // 關閉ResultSet物件 } catch(Exception e) { e.printStackTrace(); } } if (null != stat) { try { stat.close(); // 關閉statement物件 } catch(Exception e) { e.printStackTrace(); } } if (null != conn) { try { conn.close(); // 關閉連線 } catch(Exception e) { e.printStackTrace(); } } } /** * 關閉資料庫語句 statement 和 資料庫連線 conn * @param stat * @param conn */ public static void closeStatAndConn(Statement stat, Connection conn) { if (null != stat) { try { stat.close(); // 關閉statement物件 } catch(Exception e) { e.printStackTrace(); } } if (null != conn) { try { conn.close(); // 關閉連線 } catch(Exception e) { e.printStackTrace(); } } } }