SQL Server上的加密
SQL Server上內建了加密用來保護各種類型的敏感性資料。在很多時候,這個加密對於你來說是完全透明的;當資料被儲存時候被加密,它們被使用的時候就會自動加密。在其他的情況下,你可以選擇資料是否要被加密。SQL Server可以加密下列這些組件:
·密碼
·預存程序,視圖,觸發器,使用者自訂函數,預設值,和規則。
·在伺服器和使用者之間傳輸的資料
密碼加密
SQL Server自動將你分配給登陸和應用角色的密碼加密。儘管當你可以從主要資料庫中直接察看系統資料表格而不要求輸入密碼。你不能給對這種情況作出任何修改,事實上,你根本不能破壞它。
定義加密
在有些時候,如果對對象進行加密是防止將一些資訊分享給他人。例如,一個儲存進程可能包含所有者的商業資訊,但是這個資訊不能和讓其他的人看到,即使他們公開的系統資料表格並可以看到對象的定義。這就是為什麼SQL Server允許你在建立一個對象的時候進行加密。為了加密一個儲存進程,使用下面形式的CREAT PROCEDURE 語句:
CREATE PROCEDURE procedurename [;number]
[@parameter datatype
[VARYING][ = defaultvalue][OUTPUT]]
[, …]
[WITH RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION]
我們關心的僅僅是可選的WITH參數。你可以詳細說明ARECOMPILE或者ENCRYPTION,或者你可以同時說明它們。ENCRYPTION關鍵字保護SQL Server它不被公開在進程中。結果,如果ENCRYPTION在啟用的時候系統儲存進程sp_helptext就會被忽視,這個儲存進程將被儲存在使用者建立進程的文本中。如果你不想要加密,你可以使用ALTER PROCEDURE,忽略WITH ENCRYPTION子句來重新建立一個進程。
為了能夠使用加密。使用者和伺服器都應該使用TCP/IP NetworkLibraries用來串連。運行適當的Network Utility和檢查Force protocol encryption,看下錶,使用者和伺服器之間的串連將不會被加密。
加密也不能完全自由。當串連確定後,要繼續其他的構造,並且使用者和伺服器必須運行代碼來解釋加密和解釋的包裹。這裡將需要一些開銷並且當在編解碼的時候會使進程慢下來。如果網路包裹在你控制範圍之外,使用這種做法是非常好的。
加密中缺少什嗎?
你可以注意到在這個列表中缺少一些被加密的東西:你表格中的資料。在你儲存資料之前,SQL Server不會提供任何內建的工具來加密你的資料。如果你需要保護儲存在SQL Server上的資料,我們給你兩條建議:第一,你可以利用GRANT 和DENY關鍵字來控制你想哪個使用者可以在SQL Server中讀取的資料。
第二.如果你真的想對資料加密,不要設法加密碼。你可以利用被測試過的商業產品的演算法。
SQL 插入式攻擊
SQL 插入式攻擊是一個常規性的攻擊,它可以允許一些不法使用者檢索你的資料,改變伺服器的設定,或者在你不小心的時候黑掉你的伺服器。SQL 插入式攻擊不是SQL Server問題,而是不適當的程式。如果你想要運行這些程式的話,你必須明白這冒著一定的風險。
測點定位弱點
SQL 注入的脆弱點發生在程式開發員構造一個WHERE 子句伴隨著使用者的輸入的時候。比如,一個簡單的ASP程式允許使用者輸入一個顧客的ID然後檢索公司的全部人員的名字,如果顧客ID如果作為ASP頁面的請求串的一部分返回,那麼開發員可以編寫下面的代碼獲得資料:
strConn = "Provider=SQLOLEDB;Data Source=(local);" & _
"Database=Northwind;Integrated Security=SSPI"
Set cnn = Server.CreateObject("ADODB.Connection")
cnn.Open strConn
strQuery = "SELECT ContactName FROM Customers " & _
“WHERE CustomerID = '" & Request.Form("CustID") & "'"
Set rstResults = cnn.Execute(strQuery)
Response.Write(rstResults.Fields("ContactName").Value)
現在你知道什麼地方有問題了吧?如果使用者知道一個使用者的ID,他可以通過檢索來獲得全部的相應的名字。現在明白了?
獲得額外的資料
當然,對於一個攻擊程式,儘管它不知道任何顧客的ID,甚至不用去猜,它也可以獲得資料。為了完成這個工作,它將下面的文本輸入到應用程式調用顧客ID的textbox中:
customer ID:
'UNION ALL SELECT ContactName FROM Customers
WHERE CustomerID <>'
如果你輸入了這個代碼,你將會看到返回一個詢問語句:
SELECT ContactName FROM Customers
WHERE CustomerID = ''
UNION ALL SELECT ContactName FROM Customers
WHERE CustomerID <>''
通過獲得空和非空顧客的ID並集,這個查詢語句會返回資料庫中所有的相關姓名。事實上,這個UNION技術可以被用來獲得你資料庫中大多數資訊,看看這個CustomerID的值:
'UNION ALL SELECT FirstName + ' ' + LastName FROM
Employees WHERE LastName <>'
它將SQL語句變成:
SELECT ContactName FROM Customers
WHERE CustomerID = ''
UNION ALL SELECT FirstName + ' ' + LastName FROM
Employees WHERE LastName <>''
看,那就是攻擊程式從你的資料庫獲得的第一個僱員的名字。
更多的攻擊程式
如果SQL注入僅僅只有資料暴光這個弱點就已經夠糟糕的了,但是,實際上一個良好的攻擊程式可以通過這個弱點擷取你資料庫中所有的資料。看下面這個例子:
';DROP TABLE Customers;--
SQL語句變成:
SELECT ContactName FROM Customers
WHERE CustomerID = ''
; DROP TABLE Customers;-- '
這個分號使語句和SQL Server隔離,所以,這裡實際上是兩個語句。第一個語句不存在的名字,第二個則撤消的整個Customers表。兩個—SQL Server注釋符,它可以使子句不發生語法錯誤。
使用這個技術的變異,一個攻擊程式可以在任何SQL語句或者預存程序上運行。通過使用xp_cmdshell擴充預存程序,一個攻擊程式同樣可以在作業系統命令下運行,顯然,這是一個嚴重的漏洞。
保護自己的資料庫
現在,你知道如何防範SQL注入攻擊了嗎?首先,你不能在使用者輸入中構造WHERE子句,你應該利用參數來使用儲存進程。在最初的ASP頁面下,重新寫的部分將和剛才我們在表中所看到的東西相似。即使你認為在你的應用程式中沒有脆弱點,你應該遵守最小特權原則。使用我們建議的其他安全技術允許你的使用者僅僅訪問他們能夠訪問的。在你沒有發現你資料庫脆弱點的時候,只有這樣,不會使你的資料庫崩潰。
最後的建議
這就是全部的SQL Server安全系列。也許你現在不是一個全面的專家,但是你已經瞭解了很多反面。下一步就是你要保護你SQL Server資料,記住你在這裡所學到的知識,並利用到你的資料庫中保證你的資料不被那些駭客攻擊。