应用SqlParameter防止注入式攻击,打开主窗体关闭登录窗体
在创建登录窗体时,如果不注意很可能写出代码出现问题。再设计登录窗体时,初学者喜欢用这种方式进行登录设计
string sqlcon = "data source=.\\sqlexpress;database=MyCy;uid=sa;pwd=123456;"
string sql = "select *from tb_user where username = '"+txtuser.text+"' and userpwd = '"+txtpwd.text+"'";
SqlCommand cmd = new SqlCommand(sql, sqlcon);
这种方式在用户输入单引号等字符:如txtpwd为 1'or'1'='1 时,则此时sql=select *from tb_user where username = "username" and userpwd = '1'or'1'='1' ,此时显然恒成立,则起不到密码的验证作用,这种情况考虑使用SqlParameter防止注入攻击。
登录窗体详细设计过程如下:
在btnOK的click事件下添加如下代码
string sqlcon = "data source=.\\sqlexpress;database=MyCy;uid=sa;pwd=123456;"
SqlConnection sqlcon = new SqlConnection(sqlcon);
if (sqlcon.State == ConnectionState.Closed)
sqlcon.Open();
string sql = "select username,userpwd from tb_user where username = @username and userpwd = @userpwd";
try
{
SqlParameter[] parms = new SqlParameter[2];
parms[0] = new SqlParameter("@username", SqlDbType.VarChar, 50);
parms[0].Value = txtUser.Text;
parms[1] = new SqlParameter("@userpwd", SqlDbType.VarChar, 50);
parms[1].Value = txtPwd.Text;
SqlCommand cmd = new SqlCommand(sql, sqlcon);
cmd.Parameters.AddRange(parms);
using (SqlDataReader dr = cmd.ExecuteReader())
{
dr.Read();
if (dr.HasRows)
{
MainForm mainForm = new MainForm();
DialogResult = DialogResult.OK; //设置登录窗体成功后LoginForm关闭时用到
}
else
{
MessageBox.Show("用户名密码错误!");
}
}
sqlcon.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
这样就可以防止上面错误发生,当用户输入1'or'1'='1 时,1'or'1'='1当做一个整体进行验证,sql语句被解析为:sql=select *from tb_user where username = "username" and userpwd = 1'or'1'='1,提示用户密码错误,达到预防的目的。
顺便说一下,要想登录成功后关闭登录窗体,需要在Program的Main()入口点函数加上如下代码:
LoginForm login = new LoginForm();
if (login.ShowDialog() == DialogResult.OK)
Application.Run(new MainForm()); 就可以达到关闭登录窗体的效果。