2013-03-12 140 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