ADO学习笔记之注入漏洞与参数化查询
作为新手,在学习ADO程序时,使用 sql 语言查询数据时,很容易写类似如下代码:
using (SqlConnection con = new SqlConnection(ConnectionString)) { string cmdText = "select Flag from UserLogin where UserName='@UserName' and UserPwd='@Password'"; cmdText.Replace("@UserName",userName); cmdText.Replace("@Password",userPwd); using (SqlCommand cmd = new SqlCommand(cmdText, con)) {
con.Open(); ...... con.Close(); } }
在这里,通过String的Replace方法,用目标字符串替换原字符串中的占位符(不处理替换)。那么问题来了。如果userName为任意值,但userPwd="1‘ or 1='1",这样cmdTex的值就是"select Flag from UserLogin where UserName='@UserName' and UserPwd='1’ or 1='1'" 很明显,查询结果恒为真,这样即便不知道用户与密码也可以随时访问数据库。
为了解决这个问题,比较好的方法就是使用参数化查询,看下面的代码:
using (SqlConnection con = new SqlConnection(ConnectionString)) { string cmdText = "select Flag from UserLogin where UserName=@UserName and UserPwd=@Password"; using (SqlCommand cmd = new SqlCommand(cmdText, con)) { cmd.Parameters.Add(new SqlParameter("UserName", userName)); cmd.Parameters.Add(new SqlParameter("Password", userPwd)); con.Open(); ...... con.Close(); } }
在原字符串中也是用@UserName与@Password占位,但注意这里的占位符没有用 引号 引起来,再通过 SqlParameter这个类对占位符进行替换(处理后替换)。替换时对应的是一对一替换(@UserName对应UserName,@Password对应Password),并且原字符串有多少个查询参数,那么替换后也就只有这么多参数(像上面的例子,不经过处理替换导致原字符串中的参数增加了,增加的参数就是 ‘1’ )。
在写ADO代码时,通过参数化查询可以有效的避免查询漏洞。