当前位置: 首页 > news >正文

做京东网站的摘要lol怎么做直播网站

做京东网站的摘要,lol怎么做直播网站,网络科技公司logo设计,想建立什么网站LINQ - 對付 SQL Injection 的 免費補洞策略 LINQ - 對付 SQL Injection 的 免費補洞策略 作者#xff1a;黃忠成 一連串的 Mass SQL Injection 攻擊#xff0c;讓我們回憶起數年前的 SQL Injection 攻擊#xff0c;多年後的今天#xff0c;我們仍…LINQ - 對付 SQL Injection 的 免費補洞策略 LINQ - 對付 SQL Injection 的 免費補洞策略 作者黃忠成 一連串的 Mass SQL Injection 攻擊讓我們回憶起數年前的 SQL Injection 攻擊多年後的今天我們仍深陷於同樣的危機中本文詳述 SQL Injection 的歷史、肇因、解決及偵測方法更為讀者們引介全新、更加安全的防堵 SQL Injection 策略。 什麼是 SQL Injection SQL Injection中譯為 SQL 注入更為人知的名稱是【資料隱碼攻擊】意指開發人員於撰寫網頁應用程式之際貪圖一時方便或是依循前人的慣性寫法而開啟的一道門。在數年前一次大型的隱碼攻擊行動喚起了所有網站擁有者及設計人員的防駭之心讓我們認知到網站是一個曝露在所有人面前的公共園地其安全性不容忽視在那次的攻擊行動中有數千個網站遭到同一種手法入侵洩露的資料及因入侵所損失的金額難以估計而起源竟只是程式設計師的慣性及疏於防範而我們都曾經是其中一份子。 那具體上什麼是 SQL Injection 呢其實說穿了很簡單就是透過網頁上的輸入區域 (INPUT 如文字輸入框或是 URL 中的查詢字串)將特定的 SQL 語句透過網頁送往資料庫執行。以一個登入網頁為例在設計登入網頁時我們會放兩個 TextBox 控件分別讓使用者填入使用者 ID 及密碼類似畫面如下 圖 1 在使用者按下登入按鈕後我們將其輸入的資訊送往資料庫驗證使用者輸入的登入資訊是否正確 using System; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Data.SqlClient; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { if (ValidateUser(TextBox1.Text, TextBox2.Text)) Label1.Text 歡迎你; else Label1.Text 登入失敗; } private bool ValidateUser(string userName, string password) { SqlConnection conn new SqlConnection( Data SourceJEFFRAY;Initial CatalogNorthwind;Integrated SecurityTrue); using (conn) { SqlCommand cmd new SqlCommand(SELECT COUNT(*) FROM USERS WHERE USER_ID userName AND PASSWORD password , conn); conn.Open(); return ((int)cmd.ExecuteScalar() 0); } } }當你寫下這些程式碼時已經開啟了 SQL Injection 的大門了只要使用者於登入時填入下圖的資訊那麼不管 ID 密碼是什麼一律可以登入系統。 圖 2 這是為什麼呢很簡單起因於下面這行程式碼 SqlCommand cmd new SqlCommand(SELECT COUNT(*) FROM USERS WHERE USER_ID userName AND PASSWORD password , conn);我們使用傳統 ASP 常見的手法以組裝 SQL 指令的方式將使用者的輸入融入既定的 SQL 語句中但卻忽略了一件重要的事使用者可以輸入任意的字串包括了部份的 SQL 指令透過輸入部份的 SQL 指令及微調使用者可以輕易的改變這段 SQL 指令甚至是疊加另一串 SQL 指令而我們的網頁則照單全收以上的輸入會將整句 SQL 語句調整成下面這樣 圖 3 透過必然成真的條件式再加上 SQL 的註解我們的網站就這樣曝露在網路上今天我加的是 OR若是狠一點的加上 DROP TABLE 等破壞性指令網站就此拜拜。 這種攻擊不僅僅出現在上例這種 POST 狀況另一種 GET 狀態也常常受到同樣的攻擊例如下面的程式碼即開啟了 SQL Injection 的大門。 using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Data.SqlClient; public partial class QueryStringInjection : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { SqlConnection conn new SqlConnection(Data SourceJEFFRAY;Initial CatalogNorthwind;Integrated SecurityTrue); using (conn) { SqlCommand cmd new SqlCommand( SELECT * FROM Customers WHERE CustomerID Request.QueryString[ID], conn); conn.Open(); DetailsView1.DataSource cmd.ExecuteReader(CommandBehavior.CloseConnection); DetailsView1.DataBind(); } } } }試著在 URL 上鍵入 http://localhost:43236/FirstInjection/QueryStringInjection.aspx?IDVINET OR 11 --註http://localhost:43236 是你的 Web Development Server 自動產生的 Port你必須視情況修改。結果你會看到 CustomerIDVINET 以外的 ALFKI 資料列如下圖 圖 4 如果有心人士在 URL 上鍵入 DROP TABLE 或是 INSERT 的 QueryString將資料任意的刪除或插入惡意的連結 Script (詳見後述的 Mass SQL Injection 一節)那後果不堪設想。 未啟用 Custom Error Page 的漏洞 你應該已經知道寫 ASP.NET 應用程式的第一道安全手續就是啟用 Custom Error Page 功能讓駭客們無法透過預設的錯誤網頁來取得不該取得的資訊若未啟用 Custom Error Page那麼下圖是可能發生在你的網站中的 圖 5 有了這些資訊具有耐心的駭客要透過輸入不同的字元來探測整段 SQL 語句就不困難了防堵的最佳辦法就是啟用 Custom Error Page 設定 Web.config ...............略customErrors modeOn defaultRedirectDefaultError.htm/customErrors............略 一旦啟用後錯誤發生時會導向 DefaultError.html結果變成下面這樣 圖 6 檢測你的網頁有無 SQL Injection 的可能性 OK那有沒有辦法可以檢測現在的網頁是否受 SQL Injection 威脅呢如果你是網站管理者而非設計師那麼你只有依賴現在常見的網頁漏洞檢測工具對網頁進行黑箱測試不過提醒你目前的網頁漏洞測試工具大多是針對 PHP、ASP 所設計的能測出來的漏洞相當有限有時即使是安全的網頁也會因為未實作過濾法(後述)而導致誤判。 如果你是程式設計師事情就簡單的多了只要檢視一下程式碼看看動態組裝 SQL 語句的部份是否有 SQL Injection 即可圖 007 是一個確認 SQL Injection 是否存在於你的程式中的公式。 圖 7 只要你的程式中有 SQL 字串加上使用者輸入值的情況那麼該網頁存在 SQL Injection 危機的可能性就高達 99.9%。 前輩的叮嚀防止 SQL Injection 的方法 在數千個網站的入侵事件發生後許多資安專家提出了各種防範 SQL Injection 的方法其中不外乎圖 008 的四種。 圖 8 過濾法可以阻止特定字如【--】、【 OR 】、【】的輸入能有效防堵必然成真條件式及錯誤訊息顯示時的漏洞不過魔高一丈此法最後仍然遭受破解透過 SQL 的轉碼函式駭客可以將部份 SQL 語句做出編碼來逃避偵測最後突破這道防線。但由於轉碼後的字串相當長所以只要設計師細心些搭配 MaxLength 的設定還是可以讓過濾法奏效但過濾法其實很脆弱所以一定要搭配其它的手法方能行之。 下面是一個使用過濾法的例子利用引入外部 JavaScript 檔案及 Form 的 onSubmit 事件在送出資料前先檢測擁有 ci Attribute 標示的 text tag此法可運行於 IE 及 FireFox 上 Injectiondetect.js function validateInjection() { var i 0; for(i 0; i document.forms[0].elements.length;i) { if(document.forms[0].elements[i].type text document.forms[0].elements[i].getAttribute(ci) ! null) { var elem document.forms[0].elements[i]; if(elem.value ! null (elem.value.indexOf(\) ! -1 || elem.value.indexOf(--) ! -1 || elem.value.indexOf( OR ) ! -1)) { alert(possible injection detected.) return false; } } } return true; }.aspx % Page LanguageC# AutoEventWireuptrue CodeFileDefaultWithFilter.aspx.cs InheritsDefaultWithFilter % !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd html xmlnshttp://www.w3.org/1999/xhtml head runatserver titleUntitled Page/title script languagejavascript typetext/javascript srcinjectiondetect.js /script /head body form idform1 οnsubmitreturn validateInjection() runatserver div table border1 tr td使用者編號/td tdasp:TextBox IDTextBox1 citrue MaxLength12 runatserver/asp:TextBox/td /tr tr td密碼/td tdasp:TextBox IDTextBox2 citrue MaxLength12 runatserver/asp:TextBox/td /tr tr td colspan2 asp:Button IDButton1 runatserver Text登入 οnclickButton1_Click / /td /tr /table asp:Label IDLabel1 runatserver Text/asp:Label /div /form /body /html下圖是嘗試於此網頁進行 SQL Injection 攻擊時的結果 圖 9 不過這種過濾法還不完善因為資深的駭客仍然可以透過將網頁存成 HTML移除 JavaScript 認證並假造 ViewState 來對網站進行 SQL Injection 攻擊所以完善的過濾法應該是 Client 端與 Server 都有Server 端如下所示 .aspx.cs using System; using System.Collections; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Data.SqlClient; public partial class DefaultWithFilter : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } private bool DetectInjection(string input) { if (input.IndexOf() ! -1 || input.IndexOf(--) ! -1 || input.IndexOf( OR ) ! -1) return true; return false; } protected void Button1_Click(object sender, EventArgs e) { if (TextBox1.Text.Length 12 || TextBox2.Text.Length 12 || DetectInjection(TextBox1.Text) || DetectInjection(TextBox2.Text)) { ClientScript.RegisterStartupScript(typeof(Page), Alert_Msg, alert(possible injection detected.), true); return; } if (ValidateUser(TextBox1.Text, TextBox2.Text)) Label1.Text 歡迎你; else Label1.Text 登入失敗; } private bool ValidateUser(string userName, string password) { SqlConnection conn new SqlConnection( Data SourceJEFFRAY;Initial CatalogNorthwind;Integrated SecurityTrue); using (conn) { SqlCommand cmd new SqlCommand(SELECT COUNT(*) FROM USERS WHERE USERS.USER_ID userName AND USERS.PASSWORD password , conn); conn.Open(); return ((int)cmd.ExecuteScalar() 0); } } }或許你會覺得實作起來挺麻煩的但這是過濾法所需付出的代價 除了過濾法外使用低權限的帳號連結資料庫也是安全常識之一藉由降低連線帳號的權限可以讓 DROP TABLE 等破壞力超強的手法碰壁不過這種手法不應該成為唯一防堵 SQL Injection 的方式因為你不可能連 INSERT 都不給執行而 INSERT 是駭客入侵網頁的常見手法。 使用 Parameter 是目前已知一勞永逸逃離 SQL Injection 的手法將前述的程式調整成下面這樣即可讓其完全逃離 SQL Injection。 using System; using System.Collections; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Data.SqlClient; public partial class Default2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { if (ValidateUser(TextBox1.Text, TextBox2.Text)) Label1.Text 歡迎你; else Label1.Text 登入失敗; } private bool ValidateUser(string userName, string password) { SqlConnection conn new SqlConnection( Data SourceJEFFRAY;Initial CatalogNorthwind;Integrated SecurityTrue); using (conn) { SqlCommand cmd new SqlCommand( SELECT COUNT(*) FROM USERS WHERE USER_ID USER_ID AND PASSWORD PASSWORD, conn); cmd.Parameters.AddWithValue(USER_ID, userName); cmd.Parameters.AddWithValue(PASSWORD, password); conn.Open(); return ((int)cmd.ExecuteScalar() 0); } } }失效了嗎這些方法 上節提及的幾種防堵 SQL Injection 的方法在業界已經流傳許久其中使用 Parameter 更是快變成常識級的考古用知識。那為何到目前為止你仍然時常聽到某某網站遭受 SQL Injection 攻擊甚至你只要有足夠的時間及耐心用 Google 以關鍵字【登入】、【資料查詢】查詢接著以上述的【 OR 11 --】或是【】來一一測試輕輕鬆鬆就能找到幾個吃這套技巧的網站然後取得極度敏感的個人資料或是其用來查詢的 SQL 字串。 SQL Injection 至今仍然存在的原因很簡單程式設計師的惰性、慣性及大而化之的個性是導致 SQL Injection 存在於這個高安全性當道時代的最大原因。 雖然使用 Parameter 手法可以防掉所有的 SQL Injection 攻擊但在此同時也增加了需要撰寫的程式碼長度常見的結果便是設計師只會在特定敏感功能上才會使用這種手法。 在現時今日你很難當起駭客透過 SQL Injection 手法通過極大多數網站的【登入】機制原因不是程式設計師及網站管理者的細心而是這個機制曾經出了個所有人都無法忽視的大包 但 SQL Injection 只出現在這些機制上嗎你我都知道這不是真的舉個實例來說以下的查詢網頁是相當常見的。 圖 10 這個網頁允許使用者任意輸入【公司名稱】、【客戶編號】、【聯絡人】等三個欄位之搜尋字串然後進行組合查詢如果使用者僅輸入【公司名稱】那麼系統將不會把其它兩個欄位放入查詢語句中請先閉上眼睛思考著你怎麼實現這個功能如果結果是下面這樣那你已然開啟 SQL Injection 的大門了。 protected void Button1_Click(object sender, EventArgs e) { SqlConnection conn new SqlConnection( Data SourceJEFFRAY;Initial CatalogNorthwind;Integrated SecurityTrue); using (conn) { SqlCommand cmd new SqlCommand(SELECT * FROM Customers, conn); string cmdStr ; if(TextBox1.Text.Length 0) cmdStr string.Format( CompanyName LIKE %{0}% AND ,TextBox1.Text); if(TextBox2.Text.Length 0) cmdStr string.Format( CustomerID LIKE %{0}% AND ,TextBox2.Text); if(TextBox3.Text.Length 0) cmdStr string.Format( ContactTitle LIKE %{0}% AND ,TextBox3.Text); if (cmdStr.Length 0) cmd.CommandText WHERE cmdStr.Substring(0, cmdStr.Length - 5); conn.Open(); GridView1.DataSource cmd.ExecuteReader(CommandBehavior.CloseConnection); GridView1.DataBind(); } }導致我們寫下這個程式的原因有三個 圖 11 第三個原因大概是寫下此程式之設計師真正的想法那會變多長呢我們試著寫一下就知道了。 protected void Button1_Click(object sender, EventArgs e) { SqlConnection conn new SqlConnection( Data SourceJEFFRAY;Initial CatalogNorthwind;Integrated SecurityTrue); using (conn) { SqlCommand cmd new SqlCommand(SELECT * FROM Customers, conn); string cmdStr ; if (TextBox1.Text.Length 0) { cmdStr CompanyName LIKE CName AND ; cmd.Parameters.AddWithValue(CName, %TextBox1.Text%); } if (TextBox2.Text.Length 0) { cmdStr CustomerID LIKE CID AND ; cmd.Parameters.AddWithValue(CID, % TextBox2.Text %); } if (TextBox3.Text.Length 0) { cmdStr ContactTitle LIKE CTitle AND ; cmd.Parameters.AddWithValue(CTitle, % TextBox3.Text %); } if (cmdStr.Length 0) cmd.CommandText WHERE cmdStr.Substring(0, cmdStr.Length - 5); conn.Open(); GridView1.DataSource cmd.ExecuteReader(CommandBehavior.CloseConnection); GridView1.DataBind(); } }唔也不是很長嘛為了省幾行程式碼開這麼大的洞值得嗎呵程式設計師就是這種動物不是嗎 補洞的代價 在你暗笑著我怎麼可能會犯下前節的錯誤時我必須提醒你程式設計師的第二個通病那就是【以己度人】白話就是【我不會犯的錯所以別人也不會犯】在群組開發時這個情況更是履見不鮮。事實是你不會寫下這段程式碼但難保其它設計師不會畢竟都是糊口飯吃的只要補洞的工作需要付出時間代價那麼就一定有人會偷懶或粗心肇因可能是惰性、慣性也可能是你未跟他明確提及這事兒的嚴重性而後果常是我們無法承受的。 LINQ To SQL/LINQ To Entities 免費的補洞策略 除了程式設計師努力的防堵 SQL Injection 之外開發平台廠商也沒有置身事外以 Microsoft .NET 平台來說為了防堵 SQL InjectionASP.NET Team 於 ASP.NET 2.0 推出了 DataSource 控件群這組控件利用了 Parameter 的手法完全避開了 SQL Injection 的發生。但是我依舊時常聽到許多設計師抱怨【DataSource 控件用起來綁手綁腳的內部不知道在搞什麼還不如自己用 SqlCommand 來得快且直覺。】的確事實是如此DataSource 控件為了防堵 SQL Injection 所做的努力換來的是【綁手綁腳】的惡名這該歸咎於 ASP.NET Team 設計 DataSource 控件時沒有多花點心思在易用性、安全性、彈性上取得平衡點。 終於在 .NET Framework 3.5 及 Visual Studio 2008 上市後兩個免費、快速、有效的補洞策略出現在我們眼前他們就是【LINQ To SQL/LINQ To Entities】 說實話這兩個技術都不是為了 SQL Injection 而誕生的但其預設以 Parameter 手法運行的設計卻給了我們一個新的防堵 SQL Injection 的方法更好的是程式設計師不但不用為了防堵 SQL Injection 寫更多的程式碼相反的程式碼還變少了以最初的登入機制為例用 LINQ To SQL 改寫後變成下面這樣 using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; public partial class LoginWithLINQ : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { NorthwindDataContext context new NorthwindDataContext(); if( (from s1 in context.USERS where s1.USER_ID TextBox1.Text s1.PASSWORD TextBox2.Text select s1).Count() 0) Label1.Text 歡迎你; else Label1.Text 登入失敗; } }由於 LINQ To SQL 會將 LINQ 運算式轉成 SQL 語句然後將條件式一一以參數描述之故透過 SQL Profiler 工具可得知上面的程式最終送往 SQL Server 執行的語句如下 exec sp_executesql NSELECT COUNT(*) AS [value] FROM [dbo].[USERS] AS [t0] WHERE ([t0].[USER_ID] p0) AND ([t0].[PASSWORD] p1),Np0 varchar(5),p1 varchar(4),p0admin,p1test很明顯的這個技巧完全沒有 SQL Injection 的危機存在。 想加來加去又不要 SQL Injection 嗎LINQ 做給你 複合查詢常讓設計師不得不採用組裝式 SQL 語句手法而其結果也常因為使用 Parameter 會導致程式碼變複雜而循傳統手法完成該功能最後留下 SQL Injection 的漏洞。那使用 LINQ To SQL/LINQ To Entities 來改寫的話真的可以避免 SQL Injection 及簡化程式碼嗎讓實例說話吧我們以上例的複合查詢為例改寫成 LINQ To SQL 版本之程式碼如下 protected void Button1_Click(object sender, EventArgs e) { NorthwindDataContext context new NorthwindDataContext(); var baseData from s1 in context.Customers select s1; if(TextBox1.Text.Length 0) baseData from s1 in baseData where s1.CompanyName.Contains(TextBox1.Text) select s1; if (TextBox2.Text.Length 0) baseData from s1 in baseData where s1.CustomerID.Contains(TextBox2.Text) select s1; if (TextBox3.Text.Length 0) baseData from s1 in baseData where s1.ContactTitle.Contains(TextBox3.Text) select s1; GridView1.DataSource baseData; GridView1.DataBind(); }此例中我利用了 LINQ To SQL/LINQ To Entities 只在列舉資料集元素前才會開始組裝 SQL 語句的共通行為以疊加式查詢的方式來完成複合查詢的工作請特別注意這段程式碼只會送出一段 SQL 語句不是四個透過 SQL Profiler 可以證明這點 exec sp_executesql NSELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax], [t0].[NOTES], [t0].[TEST_ID] FROM [dbo].[Customers] AS [t0] WHERE ([t0].[CustomerID] LIKE p0) AND ([t0].[CompanyName] LIKE p1),Np0 nvarchar(4),p1 nvarchar(3),p0N%FR%,p1N%V%讓事實說話LINQ To SQL VS SQL Injection 我說你不一定信你可以下載範例然後對本文所提及的兩個 LINQ To SQL 網頁進行 SQL Injection 的測試圖 012 是以【 OR 11 --】手法來測試登入機制 圖 12 圖 013 是複合查詢的測試 圖 13 改用 LINQ To Entities 也是一樣的結果。 幫幫忙別自己開洞ExecuteQuery 及 ExecuteCommand 那使用 LINQ To SQL/LINQ To Entities 就能保證不被 SQL Injection 所擾了嗎那可不一定因為設計師還是常常會貪一時方便開啟 SQL Injection 的大門。基於彈性LINQ To SQL 及 LINQ To Entities 都支援直接將 SQL 語句送往資料庫執行的機制LINQ To SQL 的 ExecuteQuery 就是一個例子 protected void Button1_Click(object sender, EventArgs e) { NorthwindDataContext context new NorthwindDataContext(); string str SELECT * FROM USERS WHERE USER_ID TextBox1.Text AND PASSWORD TextBox2.Text ; int ret context.ExecuteQueryUSERS(str).Count(); if (ret 0) Label1.Text 歡迎你; else Label1.Text 登入失敗; }所以要防堵 SQL Injection使用 LINQ To SQL/LINQ To Entities 是最具成效及具經濟效益的不過前提是設計師得幫幫忙別放著有新的方便且有效率的技巧不學故意去當打洞工人。 迷思Stored Procedure 是安全的Parameter 是無敵的 的確是我告訴你使用 Parameter 是防堵 SQL Injection 最快、最有效、最完整的手法但是前題是不能與 Stored Procedure 扯上關係基於網路上的片段資料設計師總覺得如果我使用了 Stored Procedure並使用 Parameter 來傳遞參數那就對 SQL Injection 完全免疫了所有軟體專案主導者都同意當要求不明確時結果也會不明確基於防堵 SQL Injection 的大前題下許多專案主導者都會要求設計師不要在程式中組裝 SQL 語句而改用 Stored Procedure但他們卻高估了程式設計師的的理解力天才工程師以 Stored Procedure 來處理複合查詢寫下程式碼如下 protected void Button1_Click(object sender, EventArgs e) { SqlConnection conn new SqlConnection( Data SourceJEFFRAY;Initial CatalogNorthwind;Integrated SecurityTrue); using (conn) { SqlCommand cmd new SqlCommand(QueryCustomers, conn); cmd.CommandType CommandType.StoredProcedure; cmd.Parameters.AddWithValue(CompanyName, TextBox1.Text.Length 0 ? : TextBox1.Text); cmd.Parameters.AddWithValue(CustomerID, TextBox2.Text.Length 0 ? : TextBox2.Text); cmd.Parameters.AddWithValue(ContactTitle, TextBox3.Text.Length 0 ? : TextBox3.Text); conn.Open(); GridView1.DataSource cmd.ExecuteReader(CommandBehavior.CloseConnection); GridView1.DataBind(); } }正如你所見這是一段看不出問題在那的程式碼直到看到了 QueryCustomers 的預存程序你會吐血 CREATE PROCEDURE dbo.QueryCustomers ( CompanyName nvarchar(30), CustomerID nvarchar(12), ContactTitle nvarchar(30) ) AS DECLARE STR nvarchar(255) DECLARE WK nvarchar(255) SET STR SELECT * FROM Customers SET WK IF NOT CompanyName IS NULL SET WK WK CompanyName LIKE %CompanyName% AND IF NOT CustomerID IS NULL SET WK WK CustomerID LIKE %CustomerID% AND IF NOT ContactTitle IS NULL SET WK WK ContactTitle LIKE %ContactTitle% AND IF LEN(STR) 0 BEGIN SET STR STR WHERE SUBSTRING(WK,0,LEN(WK)-3) exec sp_executesql STR End ELSE exec sp_executesql STR結果就是 圖 14 一旦變成這樣就算是 LINQ To SQL/LINQ To Entities 也無法救你脫離 SQL Injection 的威脅所以你應該明確的告訴設計師SQL Injection 是由組裝式 SQL 語句而引發的得注意任何有【組裝式 SQL】發生的程式碼這當然也包含了 Stored Procedure。此例正確的 Stored Procedure 寫法如下 CREATE PROCEDURE dbo.SafeQueryCustomers ( CompanyName nvarchar(30), CustomerID nvarchar(12), ContactTitle nvarchar(30) ) AS DECLARE STR nvarchar(255) DECLARE WK nvarchar(255) SET STR SELECT * FROM Customers SET WK IF NOT CompanyName IS NULL BEGIN SET WK WK CompanyName LIKE pCompanyName AND SET CompanyName % CompanyName % END IF NOT CustomerID IS NULL BEGIN SET WK WK CustomerID LIKE pCustomerID AND SET CustomerID % CustomerID % END IF NOT ContactTitle IS NULL BEGIN SET WK WK ContactTitle LIKE pContactTitle AND SET ContactTitle % ContactTitle % END IF LEN(STR) 0 BEGIN SET STR STR WHERE SUBSTRING(WK,0,LEN(WK)-3) exec sp_executesql STR, NpCompanyName nvarchar(30),pCustomerID nvarchar(12),pContactTitle nvarchar(30), pCompanyNameCompanyName,pCustomerIDCustomerID,pContactTitleContactTitle End ELSE exec sp_executesql STR使用參數是防堵 SQL Injection 的不二法門就算是在 Stored Procedure 中亦是如此。 魔高一丈新一代的 Mass SQL Injection 手法 網頁的攻擊威脅中SQL Injection 算是相當狠毒的手法因為破壞性高所以也就更引人注目但 SQL Injection 是一種手法的統稱近日各大報的報導相信大多人都已見識到新一代的 SQL Injection 手法統稱為【Mass SQL Injection】。 此手法是利用了傳統的 SQL Injection 為進入點再利用設計師對於控件行為的熟悉度不足及忽視網頁安全性來侵入。舉個例來說我們常用 GridView 等控件來顯示資料為了某些理由我們會直接以方式來輸出列資料如下所示 % Page LanguageC# AutoEventWireuptrue CodeFileInputInjection.aspx.cs InheritsInputInjection % !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd html xmlnshttp://www.w3.org/1999/xhtml head runatserver titleUntitled Page/title /head body form idform1 runatserver div asp:LinqDataSource IDLinqDataSource1 runatserver ContextTypeNameNorthwindDataContext Selectnew (CustomerID, CompanyName, NOTES) TableNameCustomers /asp:LinqDataSource asp:GridView IDGridView1 runatserver AllowPagingTrue AutoGenerateColumnsFalse DataSourceIDLinqDataSource1 Columns asp:BoundField DataFieldCustomerID HeaderTextCustomerID ReadOnlyTrue SortExpressionCustomerID / asp:BoundField DataFieldCompanyName HeaderTextCompanyName ReadOnlyTrue SortExpressionCompanyName / asp:TemplateField HeaderTextNOTES SortExpressionNOTES EditItemTemplate asp:Label IDLabel1 runatserver Text%# Eval(NOTES) %/asp:Label /EditItemTemplate ItemTemplate asp:Label IDLabel1 runatserver Text%# Eval(NOTES) %/asp:Label /ItemTemplate /asp:TemplateField /Columns /asp:GridView /div /form /body /html很平常的程式碼不是結果也很平常 圖 15 直到你在第一筆資料的 NOTES 欄位中鍵入下面的文字 scriptalert(test)/script結果將會有所改變 圖 16 歡迎來到 Mass SQL Injection 的世界Mass SQL Injection 利用了設計師常忽略了輸出資料時要使用 Html Encode 機制的常識而進行了非毀滅性的入侵這種入侵常見於討論區、部落格或留言版上他的目的並非毀滅此網站而只是利用此漏洞來當掉此網站亦或是將此網站做為跳板以 Cross-Site Scripting (簡稱為 XSS) 的方式將使用者所輸入的資料導向另一網站而這個網站通常是駭客們所建構的無辜瀏覽此網站的人所輸入的資料就這樣被偷走了。 另一種更狠毒的手法則是利用 Cross-Site Scripting 的方式在網頁中注入惡意連結的 Script透過作業系統的漏洞如 Windows 的 MS06-014、MS07-004 來入侵使用者的電腦將網站當成跳板是第一步接著再把瀏覽器當成第二跳版最後入侵使用者的電腦。 當然你可能會說我常用的是 Bind不是 Eval 這個函式那麼我告訴你這兩者有同樣的問題存在。就算不用到 Eval 或是 Bind你偶而也會寫成下面這樣子 .aspx % Page LanguageC# AutoEventWireuptrue CodeFileInputInjection.aspx.cs InheritsInputInjection % !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd html xmlnshttp://www.w3.org/1999/xhtml head runatserver titleUntitled Page/title /head body form idform1 runatserver div div%GetDynamicHtml() %/div ..........略.......... /div /form /body /html.aspx.cs protected string GetDynamicHtml() { string str bTEST Injection/b; return str; }想像一下如果 GetDynamicHtml 函式中的 str 變數值是由資料庫取得後填入的你是否有背脊發涼的感覺了。 如何防止 防堵 Mass SQL Injection 的方法其實很簡單除了以 Parameter 或是 LINQ To SQL/LINQ To Entities 來阻檔傳統的 SQL Injection 攻擊外只要在輸出資料庫資料時記得用 HtmlEncode 即可 % Page LanguageC# AutoEventWireuptrue CodeFileInputInjection.aspx.cs InheritsInputInjection % !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd html xmlnshttp://www.w3.org/1999/xhtml head runatserver titleUntitled Page/title /head body form idform1 runatserver div asp:LinqDataSource IDLinqDataSource1 runatserver ContextTypeNameNorthwindDataContext Selectnew (CustomerID, CompanyName, NOTES) TableNameCustomers /asp:LinqDataSource asp:GridView IDGridView1 runatserver AllowPagingTrue AutoGenerateColumnsFalse DataSourceIDLinqDataSource1 Columns asp:BoundField DataFieldCustomerID HeaderTextCustomerID ReadOnlyTrue SortExpressionCustomerID / asp:BoundField DataFieldCompanyName HeaderTextCompanyName ReadOnlyTrue SortExpressionCompanyName / asp:TemplateField HeaderTextNOTES SortExpressionNOTES EditItemTemplate asp:Label IDLabel1 runatserver Text%# Eval(NOTES) %/asp:Label /EditItemTemplate ItemTemplate asp:Label IDLabel1 runatserver Text %# Server.HtmlEncode(Eval(NOTES) null ? : Eval(NOTES).ToString()) % /asp:Label /ItemTemplate /asp:TemplateField /Columns /asp:GridView /div /form /body /html圖 17 那如果執意輸出 HTML 呢那我只能建議你在輸出前查查輸出的字串中是否有 script 字樣並注意 onclick、onkeydown、onblur 等事件及 src tag 的輸出沒有必要的話就把所有的事件處理式濾掉這樣才能讓你逃出 Mass SQL Injection 的攻擊下面是一個簡單的例子允許除 script 外的 HTML 輸出。 .aspx % Page LanguageC# AutoEventWireuptrue CodeFileInputInjection2.aspx.cs InheritsInputInjection2 % !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd html xmlnshttp://www.w3.org/1999/xhtml head runatserver titleUntitled Page/title /head body form idform1 runatserver div asp:LinqDataSource IDLinqDataSource1 runatserver ContextTypeNameNorthwindDataContext Selectnew (CustomerID, CompanyName, NOTES) TableNameCustomers /asp:LinqDataSource asp:GridView IDGridView1 runatserver AllowPagingTrue AutoGenerateColumnsFalse DataSourceIDLinqDataSource1 Columns asp:BoundField DataFieldCustomerID HeaderTextCustomerID ReadOnlyTrue SortExpressionCustomerID / asp:BoundField DataFieldCompanyName HeaderTextCompanyName ReadOnlyTrue SortExpressionCompanyName / asp:TemplateField HeaderTextNOTES SortExpressionNOTES EditItemTemplate asp:Label IDLabel1 runatserver Text%# Eval(NOTES) %/asp:Label /EditItemTemplate ItemTemplate asp:Label IDLabel1 runatserver Text%# GetSafeHtml(Eval(NOTES)) %/asp:Label /ItemTemplate /asp:TemplateField /Columns /asp:GridView /div /form /body /html.aspx.cs using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; public partial class InputInjection2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected string GetSafeHtml(object o) { if (o ! null) { string o2 (string)o; if (o2.IndexOf(script,StringComparison.InvariantCultureIgnoreCase) ! -1) { while (true) { int index o2.IndexOf(script, StringComparison.InvariantCultureIgnoreCase); if (index -1) break; o2 o2.Replace(o2.Substring(index, 8), !-- ); index o2.IndexOf(/script, StringComparison.InvariantCultureIgnoreCase); o2 o2.Replace(o2.Substring(index, 9), !--); } } return o2; } return string.Empty; }}當 NOTES 值為【btest/b】時輸出結果如下 圖 18 GetSafeHtml 也適用於前例的 GetDynamicHtml 情況下 div%GetSafeHtml(GetDynamicHtml()) %/div關於 validateRequest 或許你會好奇ASP.NET 1.1 其之後的版本不是有一個 validateRequest 設定只要其值為 True那麼使用者所輸入的值將會受到 ASP.NET 的限制 (TextBox、及 URL 後帶的參數都在此限)而此值預設為 True意味著如果你沒有特別去修改 mechine.config 或是 web.config 將此值設為 False使用者是無法於 TextBox 控件或是 URL 參數中輸入【scriptalert(test)/script】等字樣的那也就沒有 Mass SQL Injection 危機了不是嗎 Web.config system.web ............ pages buffertrue validateRequesttrue / ............ /system.web圖 19 的確但這樣一來連【bTEST/b】等輸入也一併被防掉了在許多討論區及留言版中這種輸入是必要的況且ASP.NET 1.x 在 validateRequest 的驗證上有著 BUG若你未更新 ASP.NET 2.0 或是最新的 ASP.NET 1.x Service Pack那麼 Mass SQL Injection 仍然與你長伴。 那如果用的已是 ASP.NET 2.0且更新到最新版並將 validateRequest 設為 Ture 後是否就可高枕無憂了呢這我不能保證因為在BUG未被發現前都不叫 BUG而且在這個 AJAX 盛行的年代以 XMLHttpRequest 穿透 Validate Request 機制並不是不可能。所以validateRequest 絕不能做為防止 Mass SQL Injection 的唯一手段應整合 SQL Injection 的所有防範手段至少必須使用 Parameter 或是 LINQ To SQL/LINQ To Entities 來與資料庫溝通才是正道。 後記 因為網頁是隨手可得所以成為了駭客們的玩具本文所提及的僅是關於 SQL Injection 的手法其它如 DDoS 等攻擊還是很多身為網頁設計師的我們除了必須細心之外還得時常上一些安全性回報網站來擷取新知對於駭客我們必須常保初學者心態因為駭客們就是抓住程式設計師自持身經百戰的傲氣而趁虛而入。 範例解說 檔名說明Default.aspx無設防之 Login 網頁 (有 SQL Injection 危機)。Default2.aspx設防之 Login 網頁 (使用參數無 SQL Injection 危機)。DefaultWithFilter.aspx設防之 Login 網頁使用過濾法。QueryStringInjection.aspx無設防之 QueryString 網頁(有 SQL Injection 危機)。InputInjection.aspxMass SQL Injection 測試網頁 (已設防請自行調整為不設防來測試)使用LINQ To SQL。InputInjection2.aspxMass SQL Injection 測試網頁 2 (已設防採用過濾 script 手法) 使用 LINQ To SQL。QueryData.aspx簡單資料查詢頁面 (無設防有 SQL Injection 危機)。QueryData2.aspx簡單資料查詢頁面 (已設防使用參數無 SQL Injection 危機)。QueryData3.aspx複合查詢頁面 (無設防包含無設防及有設防之 Stored Procedure 手法)。QueryData4.aspx複合查詢頁面 (已設防無 SQL Injection 危機)。LoginWithLINQ.aspx設防之 Login 網頁使用 LINQ To SQL。QueryData4WithLinq.aspx設防之複合查詢頁面使用 LINQ To SQL。 http://www.microsoft.com/taiwan/msdn/columns/huang_jhong_cheng/LVSS.htm 转载于:https://www.cnblogs.com/yhb199/archive/2008/07/11/1240557.html
http://www.huolong8.cn/news/15364/

相关文章:

  • 青岛网站开发建设wordpress调用指定相关文章
  • 石家庄手机网站建设织梦网站背景音乐
  • 网站建设营销推广实训总结南宁上林网站建设
  • 爱搜索中级网站建设建设网站技术公司
  • 济南网站建设 济南货梯西安找工作哪个网站好
  • 做大型网站建设北京商场推荐
  • 安徽阜阳网站建设微信商城和网站建设
  • 南宁网站建设找建站通网站落地页怎么做
  • 人才网站建设方案做网站gzip压缩
  • 微网站内页百度推广下载安装
  • 坪洲网站建设泉州软件开发制作
  • 包装设计接单网站WordPress服务器应用镜像
  • 文山北京网站建设最好的国际贸易网站
  • 阿里巴巴国际站官网首页郑州快速建站模板
  • 大气微电影类网站织梦模板完整版登陆注册是静态网站
  • 网站弄论坛形式怎么做网站 pr
  • 宁安网站建设网络营销策划书的范文
  • 好网站建设公司九江网站制作
  • 做推广网站公司关键词排名点击软件工具
  • 镇江有哪些网站河北省住房和城乡建设厅网站主页
  • 那个做动态表情包的网站柏林网站建设
  • 网站建设 企业网站 框架科技企业网站设计
  • 自己建立网站多少钱电商平台开发需要哪些技术人员
  • 做了网站应该如何推广学做饺子馅上那个网站
  • 外贸必看网站关键词优化软件排行
  • 中国设计网官网图标seo如何优化图片
  • 做网站的去哪找私活百度网站下拉怎么做
  • 做美食网站视频株洲在线官网
  • wordpress 层实现seo网络推广知识
  • 网站后台 灰色经营网站需要什么资质