2008-09-16 20 views

回答

23

是的,有。從Wikipedia

"SELECT * FROM data WHERE id = " + a_variable + ";"

正是從這一聲明說,作者的意圖a_variable是一些相互關聯的「ID」字段明確的摘錄。但是,如果它實際上是一個字符串,那麼最終用戶可以按照他們的選擇操作語句,從而繞過對轉義字符的需要。例如,a_variable設置爲

1;DROP TABLE users

將下降(刪除) 「用戶」 表從數據庫,因爲SQL將呈現如下:

SELECT * FROM DATA WHERE id=1;DROP TABLE users;

SQL注入不是一個簡單的攻擊打。如果我是你,我會做非常仔細的研究。

+0

需要注意的是,只有當您的系統允許您一次執行多個SQL查詢時纔會發生。 PHP的`mysql_query`沒有。 – DisgruntledGoat 2009-07-22 15:05:49

15

是的,具體取決於您使用的聲明。您最好通過使用存儲過程或至少參數化查詢來保護自己。

請參閱WikiPedia預防樣本。

+0

如果我可以把你的身高調高1倍,我會的。除非你正在編寫提供參數化的驅動程序/庫,否則我不會想到任何理由來考慮其他任何保護SQL注入的理由。 – 2008-09-16 12:42:25

2

。 。 。呃約5000其他方式

也許財產以後像5; drop table employees; --

得到的SQL可能是這樣的: select * from somewhere where number = 5; drop table employees; -- and sadfsf

--開始評論)

0

這取決於你如何放在一起查詢,但實質上是。

例如,在Java中,如果你要做到這一點(故意突出的例子):

String query = "SELECT name_ from Customer WHERE ID = " + request.getParameter("id"); 

再有就是你打開自己高達注入攻擊的好機會。

Java有一些有用的工具來防範這些,比如PreparedStatements(其中你傳入一個字符串,比如「SELECT name_ from Customer WHERE ID =?」,JDBC層在替換你的token時處理轉義)但其他一些語言對此不太有幫助。

1

是的,絕對的:根據你的SQL方言等,有很多方法可以實現不使用撇號的注入。

針對SQL注入攻擊的唯一可靠防禦措施是使用數據庫接口提供的參數化SQL語句支持。

0

事情是撇號的,也許是真正的輸入,你必須通過在你的代碼中使用內聯SQL時加倍它們來逃避它們。你所尋找的是像一個正則表達式模式:

\;.*--\ 

用於提前結束真正的聲明分號,一些SQL注入後跟一個雙連字符從原來真正的聲明發表評論在尾隨SQL。在攻擊中可以省略連字符。

因此,答案是:不,僅僅刪除撇號不會保證您從SQL注入的安全性。

1

相反,試圖找出哪些字符過濾掉,我會堅持參數化查詢,而不是完全刪除問題。

6

是的,這是絕對可能的。

如果你有,你期望一個整數,使你的下一個SELECT語句的形式,那麼你就可以進入類似的話:

SELECT * FROM thingy WHERE屬性Id =

  • 5(很好的答案,沒問題)
  • 5; DROP表users; (壞,壞,壞...)

以下網站詳細介紹了進一步的經典SQL注入技術:SQL Injection cheat sheet

使用參數化查詢或存儲過程並不會更好。這些只是使用傳遞的參數進行的預先查詢,這些參數也可以作爲注入源。它也在本頁描述:Attacking Stored Procedures in SQL

現在,如果你禁止簡單的引用,你只能防止一組給定的攻擊。但不是全部。

一如既往,不要相信來自外部的數據。在這3個級別進行篩選:

  • 顯而易見的東西接口電平(下拉選擇列表是不是免費的文本字段更好)的相關數據性質的檢查
  • 邏輯電平(整型,字符串,長度) ,權限(這個用戶可以在這個頁面使用這種類型的數據)...
  • 數據庫訪問級別(轉義簡單報價...)。

玩得開心,不要忘記檢查WikiPedia的答案。

/維伊

+0

請注意,託管「SQL中的攻擊存儲過程」文章的域名現在似乎已停用。 – Funka 2010-05-20 04:06:56

2

須─即使你只是看撇號,您不希望將其刪除。你想轉義吧。你用兩個撇號替換每個撇號。

但是參數化查詢/存儲過程要好得多。

3

參數化的內聯SQL或參數化存儲過程是保護自己的最佳方法。正如其他人所指出的,僅僅剝離/轉義單引號字符是不夠的。

你會發現,我具體說說「參數」的存儲過程。如果您還原將過程的傳遞參數連接在一起,那麼僅使用存儲過程是不夠的。換句話說,將完全相同的易受攻擊的SQL語句包裝到存儲過程中並不會使其更安全。您需要在存儲過程中使用參數,就像使用內聯SQL一樣。

0

我只能重複別人說的話。參數化SQL是要走的路。當然,編寫它的代碼有點痛苦 - 但是一旦你完成了一次,那麼剪切和粘貼代碼並進行所需的修改並不難。我們有很多.Net應用程序,它們允許網站訪問者指定一系列搜索條件,並且代碼可以即時生成SQL Select語句 - 但用戶輸入的所有內容都可以進入參數。

6

我建議你傳遞變量作爲參數,而不是建立自己的SQL。否則,總會有一種做SQL注入的方式,以我們目前不知道的方式進行。

您創建的代碼則是這樣的:

' Not Tested 
var sql = "SELECT * FROM data WHERE id = @id"; 
var cmd = new SqlCommand(sql, myConnection); 
cmd.Parameters.AddWithValue("@id", request.getParameter("id")); 

如果你有像我這樣的名字以「在它的。非常煩人的是,所有'字符被刪除或標記爲無效。

你也可能想看看這個Stackoverflow question about SQL Injections

+0

這絕對是最佳做法 – 2008-09-23 03:25:21

0

當你期望的數字參數,你應該始終驗證輸入,以確保它的數值。除了有助於防止注入,驗證步驟將使應用程序更加便於用戶使用。

如果你收到ID =「你好」,當你預期的id = 1044,它總是更好的一個有用的錯誤返回給用戶,而不是讓數據庫返回錯誤的。

2

因爲這是一個相對較老的問題,我不會打擾寫了一個完整的,全面的答案,因爲這個問題的答案的大多數方面已經這裏提到一個海報或其他。
但是,我確實發現有必要提出另一個未被任何人觸及的問題 - SQL走私。在某些情況下,即使您嘗試刪除,也可以將「引述字符」走私到您的查詢中。事實上,即使您使用了正確的命令,參數,存儲過程等,這也是可能的。

查看完整的研究論文http://www.comsecglobal.com/FrameWork/Upload/SQL_Smuggling.pdf(披露,我是這方面的主要研究員),或者只是谷歌「SQL走私」。

相關問題