[英]Create database from user input with prepared statement to prevent SQL injection
[英]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;
}
相反,最好對參數使用COALESCE
或IFNULL
函數,以避免出現這種情況:
//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注入攻擊。
有關:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.