2013-03-12 162 views
0

我具有以下的認證方法:防止SQL注入在asp.net

protected void Button1_Click(object sender, EventArgs e) 
     {    
      string s; 
      s = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; 
      SqlConnection con = new SqlConnection(s); 
      con.Open(); 
      string sqlCmd; 
      sqlCmd = "SELECT Username, UserPassword FROM Benutzer WHERE Username = @Username AND UserPassword [email protected]"; 
      SqlCommand cmd = new SqlCommand(sqlCmd, con); 
      String username = tbUsername.Text.Replace("'", "''"); 
      String password = tbPassword.Text.Replace("'", "''"); 
      cmd.Parameters.AddWithValue("Username", username); 
      cmd.Parameters.AddWithValue("Password", password); 
      string CurrentName; 
      CurrentName = (string)cmd.ExecuteScalar(); 
      if (CurrentName != null) 
      { 
       Session["UserAuthentication"] = cmd.Parameters[0].ToString(); 
       Session.Timeout = 1; 
       Response.Redirect("Default.aspx"); 
      } 
      else 
      { 
       lblStatus.ForeColor = System.Drawing.Color.Red; 
       lblStatus.Text = "Benuztername/Password ungültig!"; 
      } 
     } 

是這足以防止SQL注入?我以前只是用戶名和密碼,直接進入命令是這樣的:

sqlCmd = "SELECT Username, UserPassword FROM Benutzer WHERE Username ='" + username + "' AND UserPassword ='" + pwd + "'"; 

其中username和pwd那裏只是字符串變量中的用戶名和密碼文本框的內容保存...

編輯:

確定我已經編輯我的代碼現在看起來是這樣的:

protected void Button1_Click(object sender, EventArgs e) 
     { 
      SqlConnection objcon = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()); 
      SqlDataAdapter objda = new SqlDataAdapter("[MembershipPruefen]", objcon); 
      objda.SelectCommand.CommandType = CommandType.StoredProcedure; 
      objda.SelectCommand.Parameters.Add("@Username", SqlDbType.VarChar).Value = tbUsername.Text; 
      objda.SelectCommand.Parameters.Add("@UserPassword", SqlDbType.VarChar).Value = tbPassword.Text; 
      objcon.Open(); 
      string CurrentName; 
      CurrentName = (string)objda.SelectCommand.ExecuteScalar(); 
      if (CurrentName != null) 
      { 
       Session["UserAuthentication"] = tbUsername.Text; 
       Session.Timeout = 1; 
       Response.Redirect("Default.aspx"); 
      } 
      else 
      { 
       lblStatus.ForeColor = System.Drawing.Color.Red; 
       lblStatus.Text = "Benuztername/Password ungültig!"; 
      } 
      objcon.Close();    
     } 

這是我的存儲過程:

CREATE PROCEDURE MembershipPruefen (@Username VARCHAR(50), @UserPassword VARCHAR(50)) 
AS 

SELECT Username, UserPassword FROM Benutzer WHERE Username LIKE @Username AND UserPassword LIKE @UserPassword; 

這就夠了嗎?我的網絡應用程序是否可以安全地防止SQL入侵或者還有什麼可做的事情?

+2

我可以知道爲什麼你只是不使用存儲過程和多層技術?它真的有幫助 – Marwan 2013-03-12 14:16:59

+0

,因爲我對此很新,而且我不知道從哪裏開始......我的時間有點有限,所以我必須儘快完成這項工作......我閱讀了很多文章,消毒,參數化和存儲過程通常是安全的,以防SQL注入,所以我做了第一個2,但我不知道它們是否足夠... – LeonidasFett 2013-03-12 14:23:19

+0

對你有好處,你跳過字符串連接! – Michel 2013-03-12 15:08:49

回答

1

使用預處理語句:

SqlCommand.Prepare

MSDN

2

使用存儲過程,只返回一個值來表示它存在於數據庫中(即行計數),或者如果您需要使用會話數據的用戶名等,然後只是返回用戶名。

這表明更小的DB數據的用戶:)

對於信息存儲過程:http://support.microsoft.com/kb/306574

2

使用參數化查詢(SqlCommand時使用的SqlParameter),並把用戶輸入的參數。 不要從未經檢查的用戶輸入中構建SQL字符串。 不要以爲你可以建立一個消毒程序,可以檢查用戶輸入的每一種格式錯誤。邊緣情況很容易被遺忘。檢查數字輸入可能很簡單,可以讓您安全起見,但對於字符串輸入只需使用參數。 檢查二級漏洞 - 如果這些值由用戶輸入組成,請不要從SQL表值中構建SQL查詢字符串。 使用存儲過程來封裝數據庫操作。

或者使用Prepared語句,它們將使用ORM形成,如Linq to SQL或NHibernate,它們在內部使用預準備語句。

+0

以及我檢查單引號,用雙引號取代它們...我想我得到的參數化查詢正確,因爲它似乎正在工作...現在我只需要實現存儲過程和IM好? – LeonidasFett 2013-03-12 14:35:34

+2

不要這麼做'好吧,我正在檢查單引號以用雙引號替換它們。參數應該爲你解決這個問題。 – Michel 2013-03-12 15:04:32

2

我會創建一個專用的sql服務器用戶連接到數據庫(我想你現在正在與'薩'連接?)。

這意味着你將一個新用戶添加到沒有權限的數據庫中,並且當你第一次運行應用程序時,你會得到一個sql異常,如預期的那樣說你沒有讀取權限。 您授予對新建用戶的'Benutzer'表的SELECT權限等。

當您這樣做時,即使您的連接受到攻擊,攻擊者也無法執行系統存儲過程等。

還有一件事:建議您散列密碼,這樣您的密碼就永遠不會以真實的文字讀取。 這是一篇大文章,我看到你沒有太多時間,但我強烈建議你實施哈希密碼。 http://crackstation.net/hashing-security.htm

編輯:我在您的存儲過程中看到一個LIKE,我會指出=,用戶必須輸入正確的密碼!

而我看到你從一個sql語句改變爲一個存儲過程:在前面的文本中,將表上的SELECT權限更改爲存儲過程的EXECUTE權限。

+0

好的感謝與LIKE關鍵字的提示,我改爲= ...至於加密密碼,我認爲這將是一個好主意,但我不想overinflate這個項目,因爲這是一個州考試的我只有70小時的規劃,實現和控制...關於權利管理,我認爲我會做這個代碼...就像我在我的數據庫中有一個字段「usertype」,該字段的值可以是admin,用戶,客人...所以我檢查登錄用戶的這一列,並決定他可以做什麼,不... ...我可以這樣做嗎? – LeonidasFett 2013-03-12 15:31:42

+0

對於一個簡單的項目,你可以在沒有加密的情況下完成它,但我至少會提到加密,因爲你對於審查員的強烈建議,在現實生活中你會額外花費一些時間來實現它,因爲在現實生活中它不再被接受,純文本密碼。角色可以在用戶表中,正確。保持這種項目簡單 – Michel 2013-03-12 15:43:20