2010-05-17 43 views
4

我有一個搜索表,其中用戶將能夠與所述類型的過濾器來過濾結果:防止SQL注入從形式生成的SQL - NO PreparedStmts

  • 領域[名稱],值[約翰] 刪除 規則
  • 領域姓氏],值[布萊克], 刪除規則
  • 領域有孩子],值[是], 刪除規則
  • 添加規則

因此,用戶將可以設置任意組過濾器,這將從根本上導致一個完全動態的WHERE子句。今後我也將必須執行更復雜的邏輯表達式,如

其中(名稱=約翰或名稱=尼克)AND(姓=布雷克或姓氏=伯恩),

所有10個字段的用戶可能會或可能不會過濾,我不知道用戶將設置多少個和哪些過濾器。所以,我不能使用預先準備好的語句(假定至少我們知道WHERE子句中的字段)。這就是爲什麼準備好的語句不幸出現問題,我必須用普通的舊生成的SQL來完成。

我可以採取什麼措施來保護應用程序免受SQL注入(REGEX或其他方式)?

+6

我不明白爲什麼準備好的陳述是不可能的。 – 2010-05-17 20:32:47

+0

由於可過濾的10個字段,我不知道用戶要過濾多少個字段。所以,我可能只在名稱(WHERE NAME ='XXX')或過濾更多字段(WHERE NAME ='XXX'和SURNAME ='YYY'和.....)過濾。每種可能的過濾器組合都需要一個不同的預備聲明。這就是爲什麼準備好的聲明在這裏沒有問題的原因。 – 2010-05-17 20:48:13

+1

然後動態構建並綁定準備的語句。擁有可變數量的參數從來就不是一個障礙,並且實際上比通過字符串連接處理查詢構建更容易,我認爲這是您之前做的。 – 2010-05-17 23:48:57

回答

5

Java,未經測試。

List<String> clauses = new ArrayList<String>(); 
List<String> binds = new ArrayList<String>(); 

if (request.name != null) { 
    binds.add(request.name); 
    clauses.add("NAME = ?"); 
} 

if (request.city != null) { 
    binds.add(request.city); 
    clauses.add("CITY = ?"); 
} 

... 

String whereClause = ""; 

for(String clause : clauses) { 
    if (whereClause.length() > 0) { 
     whereClause = whereClause + " AND "; 
    } 
    whereClause = whereClause + clause; 
} 

String sql = "SELECT * FROM table WHERE " + whereClause; 

PreparedStatement ps = con.prepareStatment(sql); 

int col = 1; 
for(String bind : binds) { 
    ps.setString(col++, bind); 
} 

ResultSet rs = ps.executeQuery(); 
+1

聽起來不錯,但我總是使用StringBuilder而不是String concatenation。這就是StringBuilder的原因。 – 2010-05-17 21:18:05

+0

謝謝,威爾,那將會訣竅。(+1加答案) – 2010-05-17 21:22:13

+1

這絕對是最好的辦法。將列名列入白名單,然後遍歷輸入以在預準備語句中設置參數。 – pkaeding 2010-05-17 22:26:25

2

如果向準備好的語句添加參數,它們將自動轉義。

conn = pool.getConnection(); 
String selectStatement = "SELECT * FROM User WHERE userId = ? "; 
PreparedStatement prepStmt = con.prepareStatement(selectStatement); 
prepStmt.setString(1, userId); 
ResultSet rs = prepStmt.executeQuery(); 
+0

此查詢假定記錄由userId過濾。如果按姓名過濾會怎麼樣?或者按名字和姓氏?或通過名稱和電子郵件?或通過電子郵件?其中每一個都需要一個不同的準備好的聲明。我有10個領域的用戶可能(或不可能)過濾(及其組合)。那就是爲什麼準備好的陳述在這裏沒有問題了。 – 2010-05-17 20:50:44

+0

你說得對,當我看到答案時我就明白了。另一個答案更清晰一些,所以我標記了一個。 (+1) – 2010-05-19 07:39:54

2

SQL Server: Dynamic where-clause

構建where子句動態,但使用的參數名稱做。

+0

謝謝克里斯,如果只是有一種方法來分裂答案。威爾要快2分鐘。 (1) – 2010-05-17 21:23:36