2008-12-16 48 views
3

我正在從用戶輸入中取出一個字符串,並將它以空格分隔(使用\ w)到一個字符串數組中。然後,我通過數組循環,並追加像這樣在where子句中的一部分:通過將沒有空白的輸入附加到我的查詢中,我是否容易受到SQL注入的影響?

  query += " AND (" 

       + "field1 LIKE '%" + searchStrings[i] +"%' " 
       + " OR field2 LIKE '%" + searchStrings[i] +"%' " 
       + " OR field3 LIKE '%" + searchStrings[i] +"%' " 
       + ") "; 

我覺得這是很危險的,因爲我追加用戶輸入我的查詢。但是,我知道任何搜索字符串中都沒有空格,因爲我將初始輸入分割爲空白。

是否有可能通過SQL注入攻擊?給Robert');DROP TABLE students;--實際上不會放任何東西,因爲那裏需要有空白。在那個例子中,它不會正常工作,但不會造成損害。

任何人有更多的經驗打擊SQL注入幫助我解決這個問題,或讓我放心嗎?

謝謝!

編輯:

哇,這是一個很多偉大的投入。謝謝大家回覆。我將調查全文搜索,並至少參數化我的查詢。

只是這樣我可以更好地理解問題,如果所有空白單引號都逃脫了,是否可以注入?

+0

\ w覆蓋所有可協調的空格嗎? 在使用它之前嘗試清洗用戶數據似乎更安全, – Alan 2008-12-16 22:14:24

+0

正如其他人已經說明的那樣,您仍然容易受到SQL注入的攻擊,因此您應該避開搜索字符串。但我也想發表評論,你應該使用全文搜索引擎而不是所有這些通配符搜索! – 2008-12-16 22:44:26

+0

您仍然可以使用ASCII特徵對單引號進行編碼,所以我甚至會說,不要冒險! – BenAlabaster 2008-12-17 15:51:48

回答

14

只要您允許用戶將數據輸入到這樣的查詢字符串中,您就很容易受到SQL注入的影響,應該像瘟疫一樣避免它!

你應該非常小心你如何讓searchStrings []數組被填充。你應該總是可變數據追加到您的查詢中使用參數對象:

+ field1 like @PropertyVal Or field2 like @PropertyVal Or field3 like @PropertyVal etc... 

如果你正在使用SQL Server例如

Query.Parameters.Add(new SqlParameter("PropertyVal", '%' + searchStrings[i] + '%')); 

你如何建立你是一個查詢字符串非常謹慎要在生產服務器上運行,特別是如果它有任何後果的數據!

在您的例子中,你提到的小博表

羅伯特'); DROP TABLE學生; -

而且列舉了,因爲它需要的空白,你不能做到這一點 - 但如果惡意用戶使用這樣的編碼它:

Robert');Exec(Replace('Drop_Table_students','_',Char(32)));-- 

我會說 - 更好地安全,做正確的方式。有沒有簡單的方法,以確保你趕上,否則每條場景......

5

只是有太多的方法可以得到這個錯誤,我不會依賴,如果有人告訴我:「不,這將是安全的,因爲......」

怎麼樣以某種形式逃避空白(網址編碼或somethign)。如何使用不明顯的Unicode空白字符,您的簡單測試無法檢查。如果您的數據庫支持某些不需要空白空間的惡意操作,該怎麼辦?

做正確的方法:使用PreparedStatement(或任何您的平臺用於注入安全參數化),追加並在用戶輸入前加上「%」並將其用作參數。

+0

調用存儲過程... – 2008-12-17 14:01:31

1

是的,他們仍然可以注入項目,沒有空間它可能沒有太多,但它仍然是一個漏洞。

一般而言,盲目地將用戶輸入添加到查詢中並不是一個好主意。

13

是的,這個腳本不包含任何空格,該SQL解碼回和執行的只是編碼字符: http://www.f-secure.com/weblog/archives/00001427.html

注入腳本是什麼像這樣:

DECLARE%20 @ S%20NVARCHAR(4000); SET%20 @ S = CAST(0x440045004300 4C00410052004500200040005400200076006100720063006800610072 00280032003500350029002C0040004300200076006100720063006800 610072002800320035003 500290020004400450043004C004100520045 0020005400610062006C0065005F0043007500720073006F0072002000 43005500520053004F005200200046004F0052002000730065006C0065 0063007400200061002E006E0061006D0065002C0062002E006E006100 6D0065002000660072006F006D0020007300790073006F0062006A0065 00630074007300200061002C0073007900730063006F006C0075006D00 6E00730020006200200077006800650072006500200061002E00690064 003D0062002E0069006400200061006E006400200061002E0078007400 7900700065003D00270075002700200061006E0064002000280062002E 00780074007900700065003D003900390020006F007200200062002E00 780074007900700065003D003300350020006 ...

WICH SQL解碼以:

DECLARE @T VARCHAR(255)'@ C_ VARCHAR(255)從 系統對象a'syscolumns DECLARE Table_Cursor
CURSOR FOR選擇a.name'b.name b其中 a.id = b.id和a.xtype = 'u' 和 (b.xtype = 99或b.xtype = 35或b ...

等,所以其可能做到無論你想用數據庫中的每個表而不用任何空格。

1

這裏是一個微不足道的注射,如果我將field1設置爲這個,我已經列出了數據庫中的所有行。這可能對安全性不利... ...

'+field1+' 

您應該使用參數(這些參數也適用於內聯SQL),例如,

AND Field1 = @Field1 
2

經驗法則是:如果你將字符串不是SQL,它必須使用預處理語句或從您的數據庫客戶端庫正確的「逃離」功能進行轉義。

2

我完全同意查詢參數是絕對最安全的方法。有了它們,你就不會有任何SQL注入的風險(除非你對這些參數做了一些愚蠢的處理),並且沒有任何轉義開銷。

如果您的DBMS不支持查詢參數,那麼它必須支持字符串轉義。在最糟糕的情況下,您可以嘗試自己擺脫單引號,儘管仍然存在一個Unicode漏洞可以繞過這個漏洞。但是,如果您的DBMS不支持查詢參數,則它可能不支持Unicode。 :)

加:另外。像你這樣的查詢寫了有性能殺手 - 沒有索引可以使用。我建議查看你的DBMS的全文索引功能。它們完全適用於這種情況。

相關問題