2012-03-29 106 views
3

我的老師和我正在討論是否有可能將SQL注入預準備語句。我明白,通常你不能,但教授堅持使用sql連接而不是使用(?)。SQL注入和預處理語句

現在我試圖打破我的代碼,但我沒有運氣。

public Users getUserByUsername(String username) throws SQLException { 
    StringBuffer sql = new StringBuffer(); 

    sql.append("select * from users as u, user_type_lookup as l, user_types as t "); 
    sql.append("where u.users_id=l.user_id and l.type_id=t.user_types_id and u.username='"); 
    sql.append(username); 
    sql.append("';"); 

    System.out.println(sql.toString()); 

    PreparedStatement ps = conn.prepareStatement(sql.toString()); 
    ResultSet rs = ps.executeQuery(sql.toString()); 

    if (!rs.next()) { 
     return null; 
    } 

    String password = rs.getString("password"); 
    String type = rs.getString("description"); 
    int id = rs.getInt("users_id"); 
    int incorrect_logins = rs.getInt("incorrect_logins"); 
    Time wait_time = rs.getTime("wait_time"); 

    Users u = new Users(id, username, password, type, incorrect_logins, 
      wait_time); 
    return u; 
} 

插入我曾嘗試:

string: '; DELETE FROM users WHERE 1 or users_id = ' 
string: ';delete from users where username<>' 
//The only one that worked  
string: stan' or 'a'<>'b 

SQL輸出(在Java錯誤結果):

select * from users as u, user_type_lookup as l, user_types as t where u.users_id=l.user_id and l.type_id=t.user_types_id and u.username=''; DELETE FROM users WHERE 1 or users_id = ''; 

SQL輸出(按預期工作):

select * from users as u, user_type_lookup as l, user_types as t where u.users_id=l.user_id and l.type_id=t.user_types_id and u.username='stan'; 

錯誤消息:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your  
SQL syntax; check the manual that corresponds to your MySQL server version for the 
right syntax to use near 'DELETE FROM users WHERE 1 or users_id = ''' at line 1 

服務器:Tomcat的7

數據庫:MySQL的

IDE:Eclipse的

語言:Java的

所以,請幫助我打破我的代碼!

+0

準備好的陳述包括通過其他方式轉義價值。如果值已經轉義,則應使用連接。 – kirilloid 2012-03-29 19:49:39

+0

雖然我認爲這是一個很好的問題,可以使用SQL注入攻擊來準備語句......它並不是真正的表達方式......您可能希望使它更像是一個問題,以至於答案可以提供。 – scunliffe 2012-03-29 19:50:23

+2

即使您能夠將SQL注入該語句中,您也可以通過編寫代碼的方式來執行此操作。這是*不是*準備好的聲明。 – NullUserException 2012-03-29 19:52:37

回答

4

您不能添加一個單獨的語句準備語句的SQL內,但您可以通過打破它,例如:

  • 使用' OR 'x' = 'x作爲用戶名(以便查詢會對所有用戶和他們之間的類型映射進行笛卡爾連接);如果usersuser_type_lookup是大型表,這將極大地損害性能,並且這將是拒絕服務攻擊的絕佳開始。
  • 使用' OR (SELECT stored_procedure_that_deletes_things()) = 1(以便查詢將調用具有有害效果的存儲過程)。