一、SQL注入漏洞攻击
1、登录判断:select * from T_Users where UserName=... and Password=...,将参数拼到SQL语句中。
2、构造恶意的Password:' or '1'='1
if (reader.Read())
{
Console.WriteLine("登录成功");
}
else
{
Console.WriteLine("登录失败");
}
如:
using (SqlCommand cmd = conn.CreateCommand())
{
string password = "' or '1'='1";
cmd.CommandText = "select * from T_Users where UserName='admin' and Password='" + password+"'";
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
Console.WriteLine("登录成功");
}
else
{
Console.WriteLine("登录失败");
}
}
}
3、防范注入漏洞攻击的方法:不使用SQL语句拼接,通过参数赋值。
二、查询参数
4、SQL语句使用@UserName表示“此处用参数代替”,向SqlCommand的Parameters中添加参数:
cmd.CommandText = "select * from T_Users where UserName=@UserName and Password=@Password";
cmd.Parameters.Add(new SqlParameter("UserName","admin"));
cmd.Parameters.Add(new SqlParameter("Password",password));
5、参数在SQLServer内部不是简单的字符串替换,SQLServer直接用添加的值进行数据比较,因此不会有注入漏洞攻击。
6、将连接字符串写在代码中的缺点:多次重复,违反了DRY(Don't Repeat Yourself)原则;DRY俗话就是:不要拷代码。如果要修改连接字符串就要修改代码。将连接字符串写在App.Config中:
- 添加App.config文件(文件名不能改):添加→新建项→常规→应用程序配置文件。App.config是.Net的通用配置文件,在ASP.Net中也能同样使用。
- 在App.config中添加connectionStrings段,添加一个add项,用name属性起一个名字(比如DbConnStr),connectionString属性指定连接字符串。
- 在“引用”节点上点右键“添加引用”,找到System.configuration。不是所有.Net中的类都能直接调用,类所在的Assembly要被添加到项目的引用中才可以。
- ConfigurationManager.ConnectionStrings[" DbConnStr "].ConnectionString得到连接字符串。
- 如何在部署的程序中修改配置。
7、案例:省市选择程序:
(1)ComboBox的显示值:Items.Add的参数是Object类型,也就是可以放任意数据类型的数据,可以设置DisplayMember属性设定显示的属性,通过SelectedItem属性取得到就是选择的条目对应的对象。例子。疑问:取出来的是Object,怎么能转换为对应的类型?变量名只是“标签”。显示的值和实际的对象不一样,在ASP.Net中也有相同的东西。
(2)创建一个ProvinceItem类,将数据填充在这个对象中添加到ComboBox中。
(3)代码:
private void Form1_Load(object sender, EventArgs e)
{
string connStr = ConfigurationManager.ConnectionStrings["DbConn"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from promary";
using (SqlDataReader dataReader = cmd.ExecuteReader())
{
while (dataReader.Read())
{
ProvinceItem item = new ProvinceItem();
item.Id = dataReader.GetInt32(dataReader.GetOrdinal("proID"));
item.Name = dataReader.GetString(dataReader.GetOrdinal("proName"));
cmbProvince.Items.Add(item);
}
}
}
}
}
private void cmbProvince_SelectedIndexChanged(object sender, EventArgs e)
{
cmbCity.Items.Clear();
ProvinceItem item = (ProvinceItem)cmbProvince.SelectedItem;
string connStr = ConfigurationManager.ConnectionStrings["DbConn"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from city where proID=@proID";
cmd.Parameters.Add(new SqlParameter("proID",item.Id));
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
string cityName = reader.GetString(reader.GetOrdinal("cityName"));
cmbCity.Items.Add(cityName);
}
}
}
}
}
}
public class ProvinceItem
{
public int Id { get; set; }
public string Name { get; set; }
}