2014-02-21 107 views
0

我正在嘗試解決可能的問題使用AS400傳輸時的SQL電流消耗。解決方案之一是通過添加編碼來更改查詢。 EX:"select * from address where city='bellevue' "將被替換爲:"select * from address where city=''bellevue'' "。該查詢拋出異常:java.sql.SQLException:[SQL0101]Token bellevue was not valid. Valid tokens:FOR....Oracle,MySQL似乎沒有問題執行相同類型的查詢,但DB2/AS400不喜歡它。只有一個「'」,查詢效果很好。使用JDBC連接驅動程序:com.ibm.as400.access.AS400JDBCDriver。任何想法爲什麼?db2/AS400 SQLException標記無效

+0

問:您可以成功使用單引號('),是否正確?如果是這樣,問題是什麼? – FoggyDay

+0

正確,單引號工作正常。我試圖通過轉義用戶的輸入來保護查詢(請參閱鏈接:https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet)。他們完美的解決方案是使用PreparedStatement,但在我們的案例中,查詢由用戶輸入而生成,因此解析查詢和生成PreparedStatement有點昂貴。轉義是另一種方式,這就是爲什麼我們用2個單引號替換單引號。 – galina62

回答

0

您試圖阻止SQL注入。它看起來像你已經看到用雙撇號('')取代單撇號(')的消解。但他們只是在談論用戶輸入的內容,而不是圍繞它。

讓我們來看看這樣的攻擊可能如何工作。你給用戶一個你想讓他們輸入城市名稱的字段。你想在你的查詢中使用該值。

query := "select * from address where upper(city)=upper('" || input_city || ")'" 

然後你會發送這個查詢字符串,由數據庫服務器解釋。一切都很好,如果他們輸入bellvueNEW YORK。但想想看,如果他們輸入Washington's Crossing會發生什麼,那麼你有問題。查詢字符串的第一部分以撇號結尾以啓動字符串文字,但城市名稱中的撇號將結束文字並且s Crossing將導致語法錯誤。

現在想象一下,如果有人知道這件事,並且對他們的投入有創意,會發生什麼?我們來看幾個。

x' or '1'='1 
'; select * from tablescatalog where table_name >' 
'; delete from customers where name<>' 

或其他可能會更糟糕的值。現在您可以看到爲什麼它是動態構建查詢時需要特別注意的輸入字段。在查詢字符串中使用它之前,您需要處理似是而非的字符。

或者,您可以PREPARE參數化查詢。這通常是一種更安全的方法。它也表現得更好。

+0

[漫畫](https://xkcd.com/327/)和[解釋](http://www.explainxkcd.com/wiki/index.php/Little_Bobby_Tables) – WarrenT

+0

感謝您的回覆。我同意使用參數化查詢的PrepareStatement更加節省和更好地執行。我們的應用程序允許用戶通過鍵入WHERE子句(用戶將輸入WHERE CITY ='BELLEVUE')。你知道任何將用戶輸入轉換爲參數化查詢的開源產品嗎?我在看SQL解析器,但它是商業產品。 – galina62

+0

您提供查詢,問號作爲參數的位置標記。您準備好該語句,然後執行該語句(或將其作爲遊標打開),以提供用戶輸入作爲參數值。由於它已經準備好了,語法已經確定了;用戶的輸入不能被解釋爲其他任何東西。 – WarrenT