防止SQL注入攻击。 注:内容来自MSDN。
代码1-1

private void cmdLogin_Click(object sender, System.EventArgs e)
{
string strCnx =
"server=localhost;database=northwind;uid=sa;pwd=;";
SqlConnection cnx = new SqlConnection(strCnx);

cnx.Open();

//This code is susceptible to SQL injection attacks.
string strQry = "SELECT Count(*) FROM Users WHERE UserName='" +
txtUser.Text + "' AND Password='" + txtPassword.Text + "'";
int intRecs;

SqlCommand cmd = new SqlCommand(strQry, cnx);
intRecs = (int) cmd.ExecuteScalar();


if (intRecs>0)
{
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false);
}

else
{
lblMsg.Text = "Login attempt failed.";
}

cnx.Close();
}

上面这段代码容易被SQL注入攻击成功。
看一下查询语句:
string strQry = "SELECT Count(*) FROM Users WHERE UserName='" +
txtUser.Text + "' AND Password='" + txtPassword.Text + "'";
如果是正常的用户登录则查询语句会是如下这种形式:
SELECT Count(*) FROM Users WHERE UserName='Paul' AND Password='password'
但是,如果有人输入的用户名是 ' Or 1=1 – 则查询语句就变成了:
SELECT Count(*) FROM Users WHERE UserName='' Or 1=1
这样的话 1=1 地球都知道这结果是True
如何防范?
把代码1-1写成代码1-2(推荐)或1-3的形式,看看就明白其中的道理了。
//代码1-2存储过程参数(强烈推荐使用存储过程)

private void cmdLogin_Click(object sender, System.EventArgs e)
{
string strCnx =
ConfigurationSettings.AppSettings["cnxNWindBetter"];
using (SqlConnection cnx = new SqlConnection(strCnx))

{
SqlParameter prm;

cnx.Open();

string strAccessLevel;

SqlCommand cmd = new SqlCommand("procVerifyUser", cnx);
cmd.CommandType= CommandType.StoredProcedure;

prm = new SqlParameter("@username",SqlDbType.VarChar,50);
prm.Direction=ParameterDirection.Input;
prm.Value = txtUser.Text;
cmd.Parameters.Add(prm);

prm = new SqlParameter("@password",SqlDbType.VarChar,50);
prm.Direction=ParameterDirection.Input;
prm.Value = txtPassword.Text;
cmd.Parameters.Add(prm);

strAccessLevel = (string) cmd.ExecuteScalar();


if (strAccessLevel.Length>0)
{
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false);
}

else
{
lblMsg.Text = "Login attempt failed.";
}
}
}


//代码1-3 命令参数

private void cmdLogin_Click(object sender, System.EventArgs e)
{
string strCnx = ConfigurationSettings.AppSettings["cnxNWindBad"];
using (SqlConnection cnx = new SqlConnection(strCnx))

{
SqlParameter prm;

cnx.Open();

string strQry =
"SELECT Count(*) FROM Users WHERE UserName=@username " +
"AND Password=@password";
int intRecs;

SqlCommand cmd = new SqlCommand(strQry, cnx);
cmd.CommandType= CommandType.Text;

prm = new SqlParameter("@username",SqlDbType.VarChar,50);
prm.Direction=ParameterDirection.Input;
prm.Value = txtUser.Text;
cmd.Parameters.Add(prm);

prm = new SqlParameter("@password",SqlDbType.VarChar,50);
prm.Direction=ParameterDirection.Input;
prm.Value = txtPassword.Text;
cmd.Parameters.Add(prm);

intRecs = (int) cmd.ExecuteScalar();


if (intRecs>0)
{
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false);
}

else
{
lblMsg.Text = "Login attempt failed.";
}
}
}

