2013-07-08 118 views
0

這是我的應用程序的查詢模塊中的一個關鍵字衝突問題,請看看您是否可以告訴我一個聰明的解決方案。SQL注入的智能解決方案

首先,在查詢模塊,每個查詢條件包含在UI三個部分:

1.field的名字,它的值是固定的,如產地,finalDest ...

2.operator,它是一個包含「like」,「not like」,「in」,「not in」,「=」,「!=」的選擇列表。

3.value,這部分是用戶輸入的,結束時,它將根據UI的查詢條件組裝SQL語句,例如,如果用戶在UI中鍵入/選擇以下內容:

Field Name  Operator  Value 
origin   like   CHI 
finalDest  in    SEL 

在後端,它會生成以下SQL:

SELECT * FROM預訂原屬LIKE '%CHI%' 和finalDest在( 'SEL')。

但有一個bug,例如,如果用戶在「value」中鍵入某些特殊符號,例如「'」,「_」等,它將導致生成的SQL也包含'或_,例如:

從預訂中選擇*來源如'%C_HI%'和finalDest('S'EL')。

,你可以看到,因爲在「地方」塊時,SQL無法執行

對於這個問題的特殊符號,我的解決辦法是添加「/」中的特殊符號前面之前轉義字符執行它,但我知道只是'或_會與SQL關鍵字衝突,你知道是否有其他類似的符號需要處理嗎?或者你們有沒有更好的想法可以避免注入

對不起,忘了告訴你我在用什麼語言,我用的是java,DB是mysql,我也用hibernate,有很多人說爲什麼我沒有用PreparedStatement,這有點複雜,只是簡單speakin g,在我的公司中,我們有一個名爲動態查詢的FW,我們在一個XML文件中預先定義了SQL片段,然後我們將根據UI標準用jxel表達式組裝SQL片段,因爲SQL有點類似於預先定義的東西,我害怕如果改變使用PreparedStatement,它會涉及我們FW的很多變化,所以我們關心的只是如何用簡單的方法修復SQL注入問題。

+0

想必您發送該查詢到服務器,服務器應具有唯一的客戶端可以訪問驗證方案,客戶端應該清理它的數據庫輸入。 – awiebe

+0

您使用哪種服務器端語言? –

+0

嗨,我使用mysql5 + hibernate,但我認爲它不應該依賴於mysql,並且應該是一個通用的跨平臺SQL語句 – Chailie

回答

1
0 An ASCII NUL (0x00) character. 
' A single quote (「'」) character. 
" A double quote (「"」) character. 
b A backspace character. 
n A newline (linefeed) character. 
r A carriage return character. 
t A tab character. 
Z ASCII 26 (Control+Z). See note following the table. 
\ A backslash (「\」) character. 
% A 「%」 character. See note following the table. 
_ A 「_」 character. See note following the table 

Reference

Stack Similar Question

+0

不確定0,雙引號會衝突SQL標準。 – Chailie

2

在將任何信息發送到數據庫之前,代碼應該開始嘗試在服務器端停止SQL注入。我不確定你使用的是什麼語言,但這通常是通過創建一個包含某種綁定變量的語句來完成的。在Java中,這是一個PreparedStatement,其他語言包含相似的功能。

在語句中使用綁定變量或參數將利用內置保護防止SQL注入,這實際上比我們在數據庫上編寫的任何內容都要好。如果您在服務器端進行任何String級聯以形成完整的SQL語句,則這是SQL注入風險的一個指標。

+0

是的,你是對的,但我們是我們的地方,如果改變使用PreparedStatement,我認爲這會影響很多我們認爲它已經穩定的編碼。我們需要做的是使用智能解決方案來解決注入問題,無論使用轉義字符或其他方式,我希望這種改變不會太多。 – Chailie

+0

@Chailie如果你使用休眠,它應該已經使用PreparedStatements –

+0

我們寫的是這樣的:em = emf.createEntityManager(); 查詢查詢= em.createNativeQuery(sql); ret = query.getResultList();但是如果我在用戶界面中鍵入單引號,它將會有下面的異常:17:34:40,927錯誤JDBCExceptionReporter:101 - 你的SQL語法錯誤;檢查與您的MySQL服務器版本相對應的手冊,以便在第1行的BaseBookingInfoTO.bookingDateGMT desc處使用'%'順序附近的正確語法。 17:34:40,929錯誤AbstractEntityManagerImpl:580 - 無法在PersistenceException上標記回滾: java.lang.IllegalStateException:無事務st ... – Chailie

0

你應該在你的SQL語句使用綁定變量。如前所述,這是通過Java中的PreparedStatements完成的。

爲了確保只使用有效的列名,您可以根據數據庫驗證輸入。 MySQL提供模式信息,如每個表的列作爲INFORMATION_SCHEMA的一部分。欲瞭解更多信息,請查看MySQL文檔:

"The INFORMATION_SCHEMA COLUMNS Table"

+0

感謝您的回答,但在我的情況下,SQL語句是動態assemble.so我害怕我不能使用PreparedStatement直接 – Chailie