著名的sql注入問題-問題的原因分析及總結


Statement安全漏洞(sql注入問題)
問題展示:

首先我的Mysql數據庫中有一張users表,如下圖所示

	/**
	 * 根據用戶名查詢用戶
	 * @param username 需要查詢的用戶名
	 * @return User 記錄對應的JavaBean對象
	 */
	public static User find(String name){
		Connection conn = null;
		Statement sta = null;
		ResultSet re = null;
		User user = null;
		try{
			//獲取JavaApp與Mysql數據的連接
			conn = JDBCUtils.getConnection();
			//創建封裝SQL語句的對象
			sta = conn.createStatement();
			//執行sql語句返回結果集合'or true or'
			String sql = "select id,username,password,email,Date from users where username='"+ name + "'";
			re = sta.executeQuery(sql);
			while(re.next()){
				int id = re.getInt("id");
				String username = re.getString("username");
				String password = re.getString("password");
				String email = re.getString("email");
				Date d = re.getDate("Date");
				user = new User(id,username,password,email,d);
			}
			
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException("根據用戶名查詢失敗");
		}finally{
			JDBCUtils.close(re);
			JDBCUtils.close(sta);
			JDBCUtils.close(conn);
		}
		return user;
	}
	
	public static void main(String[] args) {
          //我們查找的是表中已有的數據李四 User user = Demo2_find.find("李四"); System.out.println(user == null ? "查無此人" : "查有此人"); }
 
        

  運行上面這段代碼,程序返回的結果是李四在Mysql數據庫確實存在,為了驗證測試效果,

這一次,我將上圖中標紅的部分User user = Demo2_find.find("李四");改為查找王五這個人,大家都知道王五這個人在數據庫是不存在的.這次運行的結果為進一步證明,上面的代碼是沒有問題的,這是我依舊將標紅部分的代碼改掉,改成User user = Demo2_find.find("'or true or'");這時會發生什么神奇的效果呢?我們運行代碼看一下.

為了讓大家看的清楚一點,我將整張屏幕截取了下來

我們可以發現,當我們輸入'or true or'進行查詢的時候竟然通過了,能夠查詢到Mysql中的數據.

這就是著名的sql注入問題.

 產生原因:

  因為SQL語句拼接,傳入了SQL語句的關鍵字,繞過了安全檢查.
客戶端利用JDBC-【Statement】的缺點,傳入非法的參數,從而讓JDBC返回不合法的值,我們將這種情況下,統稱為SQL注入。
解決方案:
  使用PreparedStatement對象就可以解決。PreparedStatement對象預處理對象。允許使用占位符對SQL語句中的變量進行占位。對SQL語句進行預先編譯。傳入SQL語句的關鍵字,不會被當成關鍵字而是普通的字符串。包括:程序執行時動態為?符號設置值,安全檢查,避免SQL注入問題,預處理能力

 

select * from user where username = ? and password = ?

Statement與PreparedStatement的區別
  現在項目中都不直接用Statement了,而用PreparedStatement。
PreparedStatement它除了具有Statement是所有功能外,
還有動態SQL處理能力,包括:程序執行時動態為?符號設置值,安全檢查,避免SQL注入問題,預處理能力。

Statement只能處理靜態SQL
  1,PreparedStatement既能處理靜態SQL,又能處理動態SQL,它繼承了Statement的特點
  2,站在預處理這個角度來說的:
  PreparedStatement【適合】做連續多次相同結構的SQL語句,有優勢。
  Statement【適合】做連續多次不相同結構的SQL語句,有優勢。
  適合:是只效率會更高,但並不表示一定要這才樣
  3,PreparedStatement
  1_支持動態SQL,也支持靜態SQL
  2_預處理
---相同結構的SQL
  select id,name from users where id = 1
  select id,name,gender from users where id = 2;
 是不相同結構
---不同結構的SQL
聲明:
  靜態SQL也可以用PreparedStatement
適合:
  靜態SQL---優先Statement


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM