簡體   English   中英

防止該語句被SQL注入

[英]Prevent this statement from SQL injection

我正在嘗試使用PreparedStatement類編寫一個非常簡單的查詢。 我在這里讀到: 無法轉換為內部表示形式的JDBC ,您不能參數化列名,只能參數化值。 由於查詢非常簡單,因此我可以參數化的唯一“值”是count (*)

這是查詢: SELECT COUNT (*) FROM EZ_DAY

如果我嘗試像這樣對它進行參數化: SELECT ? FROM EZ_DAY SELECT ? FROM EZ_DAY

我收到一個錯誤:在ResultSet上使用方法getInt()時, Fail to convert to internal representation ResultSet

如何使用PreparedStatement並在此查詢中參數化某些內容以防止SQL注入? 我也知道您不能參數化列名,其中是否包括表名? 例如,我可以做類似的事情:

SELECT COUNT (*) FROM ?

該查詢不能屬於SQL注入。 屬於此類別的查詢是您通過純字符串連接構建的那些查詢。 例如:

String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colX = " + stringParameter;
Statement stmt = con.createStatement(query);
ResultSet rs = stmt.executeQuery();

在您的情況下,沒有要注入的參數,因此無法針對您的特定情況進行SQL注入攻擊。

如果需要防止SQL注入攻擊,請使用PreparedStatement且不要串聯查詢。 而是通過接口傳遞參數,該接口將為您轉義任何無效字符:

String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colX = ?";
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1, stringParameter);
ResultSet rs = pstmt.executeQuery();

如果您需要構建動態查詢,則可能會退回到串聯字符串,無論您使用純字符串串聯還是StringBuilder

//Common solution, still suffers from SQL injection
String query = "SELECT COUNT(*) FROM EZ_DAY WHERE 1 = 1 ";
if (stringParameter != null) {
    query = query + = "AND colX = " + stringParameter;
}

相反,最好對參數使用COALESCEIFNULL函數,以避免出現這種情況:

//Better solution
String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colx = COALESCE(?, colx)";

在上述情況下:

  • 如果參數的值不同於null ,則查詢將如下所示:

     String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colx = ?"; 
  • 如果參數具有null值,則查詢將如下所示:

     String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colx = colx"; 

在最后一個示例中,您仍然可以使用PreparedStatement並避免SQL注入攻擊。

有關:

正如在解釋這個帖子 ,SQL注入可能會導致像非常嚴重的問題:

  • 調用sleep函數,以便所有數據庫連接都將繁忙,因此使您的應用程序不可用
  • 從數據庫中提取敏感數據
  • 繞過用戶認證

不僅SQL會受到影響。 如果不使用綁定參數,則即使JPQL也會受到損害。

最重要的是,在構建SQL語句時,絕對不要使用字符串連接。 為此使用專用的API:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM