我有一個特殊情況要求我從用戶提供的輸入值生成部分SQL WHERE子句。我想防止任何種類的SQL注入漏洞。我想出了下面的代碼:如何在PostgreSQL中使用Java安全地轉義SQL中的任意字符串
private String encodeSafeSqlStrForPostgresSQL(String str) {
//Replace all apostrophes with double apostrophes
String safeStr = str.replace("'", "''");
//Replace all backslashes with double backslashes
safeStr = safeStr.replace("\\", "\\\\");
//Replace all non-alphanumeric and punctuation characters (per ASCII only)
safeStr = safeStr.replaceAll("[^\\p{Alnum}\\p{Punct}]", "");
//Use PostgreSQL's special escape string modifier
safeStr = "E'" + safeStr + "'";
return safeStr;
}
問題:
- 你看到的任何問題?
- 您能否提供更好的解決方案?
- 是否有任何現有的庫來幫助這個?
注:
這是SO和其他地方的一個共同的問題,但我見過的唯一的答案是經常使用的PreparedStatement。 Fwiw,我正在使用JasperReports。我想保留JasperReports中的查詢。查詢參數處理(包括X {}函數)的內置Jasper參數函數不足以滿足我需要的參數化。我可以嘗試創建一個自定義的Jasper QueryExecutor,它允許我注入自己的X {}函數,但這比使用Jasper的$ P!{}語法生成動態SQL where子句更復雜。我看了一下OWASP libraries。他們還沒有PostgresSQL編解碼器。儘管我看着OracleCodec,但它的逃逸看起來很簡單。我不確定這對防止SQL注入攻擊有多大幫助。
在我的代碼中,我添加了E,以便不依賴於PostgreSQL的standard_conforming_strings設置。理想情況下,我不必添加它,然後該函數不必是PostgreSQL特定的。更多信息:http://www.postgresql.org/docs/9.0/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE。
理想我會一直喜歡,我就知道會是安全的,支持所有可能的UTF-8字符串更通用的和可靠的解決方案。
'BaseConnection.escapeString()'似乎涵蓋了這個http://jdbc.postgresql.org/development/privateapi/org/postgresql/core/BaseConnection.html#escapeString(java.lang.String) – 2012-03-16 17:05:54
@FrankFarmer Great想看看JDBC驅動程序的來源。查看BaseConnection將我帶到Utils類:http://jdbc.postgresql.org/development/privateapi/org/postgresql/core/Utils.html。查看源代碼,他們打開符合標誌,然後轉義與我所做的相似的引號/撇號。他們只對\ 0角色進行特殊處理,並讓其他所有元素都通過。所以......我想這是安全的,我刪除\ 0以外的每個非標準字符都是矯枉過正的?隨時發表您的評論作爲我可以接受的答案。 – kaliatech 2012-03-16 18:00:34