使用参数化查询防止SQL注入漏洞
作者:heero 来源:heero博客 发布时间:2010-06-26 12:56:00
SQL注入漏洞曾经是Web应用程序的噩梦,CMS、BBS、Blog无一不曾受其害。
SQL注入的原理
以往在Web应用程序访问数据库时一般是采取拼接字符串的形式,比如登录的时候就是根据用户名和密码去查询:
string sql = "SELECT TOP 1 * FROM [User] WHERE UserName = '" + userName + "' AND Password = '" + password + "'";
其中userName和password两个变量的值是由用户输入的。在userName和password都合法的情况下,这自然没有问题,但是用户输入是不可信的,一些恶意用户只要用一些技巧,就可以绕过用户名、密码登录。
假设password的值是"1' or '1' = '1",userName的值随便取,比如是"abc",那变量sql的值就是:
"SELECT TOP 1 * FROM [User] WHERE UserName = 'abc' AND Password = '1' or '1' = '1'"
由于'1' = '1'恒为真,因此只要User表中有数据,不管UserName、Password的值是否匹配,这条SQL命令准能查出记录来。就这样,登录系统就被破解了。
以往的防御方式
以前对付这种漏洞的方式主要有三种:
字符串检测:限定内容只能由英文、数字等常规字符,如果检查到用户输入有特殊字符,直接拒绝。但缺点是,系统中不可避免地会有些内容包含特殊字符,这时候总不能拒绝入库。
字符串替换:把危险字符替换成其他字符,缺点是危险字符可能有很多,一一枚举替换相当麻烦,也可能有漏网之鱼。
存储过程:把参数传到存储过程进行处理,但并不是所有数据库都支持存储过程。如果存储过程中执行的命令也是通过拼接字符串出来的,还是会有漏洞。
参数化查询
近年来,自从参数化查询出现后,SQL注入漏洞已成明日黄花。
参数化查询(Parameterized Query 或 Parameterized Statement)是访问数据库时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值。
在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有指令,也不会被数据库运行。Access、SQL Server、MySQL、SQLite等常用数据库都支持参数化查询。
在ASP程序中使用参数化查询
ASP环境下的参数化查询主要由Connection对象和Command对象完成。
Access数据库只支持匿名参数,在传入参数的位置用问号代替即可。SQL Server数据库虽然支持匿名和非匿名的参数,但是在ASP中也仅能使用匿名参数。
var conn = Server.CreateObject("ADODB.Connection");
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("Test.mdb");
conn.Open();
var cmd = Server.CreateObject("ADODB.Command");
cmd.ActiveConnection = conn;
cmd.CommandType = 1;
cmd.CommandText = "SELECT TOP 1 * FROM [User] WHERE UserName = ? AND Password = ?";
cmd.Parameters.Append(cmd.CreateParameter("@UserName", 200, 1, 20, "user01"));
cmd.Parameters.Append(cmd.CreateParameter("@Password", 200, 1, 16, "123456"));
var rs = cmd.Execute();
Response.Write(rs("UserId").value);
rs.Close();
conn.Close();
在ASP.NET程序中使用参数化查询
ASP.NET环境下的查询化查询也是通过Connection对象和Command对象完成。如果数据库是SQL Server,就可以用有名字的参数了,格式是“@”字符加上参数名。
SqlConnection conn = new SqlConnection("server=(local)\\SQL2005;user id=sa;pwd=12345;initial catalog=TestDb");
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT TOP 1 * FROM [User] WHERE UserName = @UserName AND Password = @Password");
cmd.Connection = conn;
cmd.Parameters.AddWithValue("UserName", "user01");
cmd.Parameters.AddWithValue("Password", "123456");
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
int userId = reader.GetInt32(0);
reader.Close();
conn.Close();
MySQL的参数格式与SQL Server有点区别,是以“?”加上参数名。
MySqlConnection conn = new MySqlConnection("server=127.0.0.1;uid=root;pwd=12345;database=test;");
conn.Open();
MySqlCommand cmd = new MySqlCommand("SELECT * FROM `User` WHERE UserName = ?UserName AND Password = ?Password LIMIT 1");
cmd.Connection = conn;
cmd.Parameters.AddWithValue("UserName", "user01");
cmd.Parameters.AddWithValue("Password", "123456");
MySqlDataReader reader = cmd.ExecuteReader();
reader.Read();
int userId = reader.GetInt32(0);
reader.Close();
conn.Close();


猜你喜欢
- Windows下打造完美的服务器平台(APACHE+JSP+CGI+PHP+ASP+MYSQL)需要下载几个软件包:1. php-5.0.2
- 核心提示:网站的存在就已经不是一个个人行为了,因为你面向的是一个广泛的群体,而非只是针对性的自己一个人,因此,网站的运营过程中,就必经有人加
- DedeCms V5.3 发布后,相对于以前的版本,各方面都表现得比较完美,不过因为通用性原因,不可能同时满足所有用户的需求的,在以往,不少
- 交换友情链接是快速增加反链接的最有效的方法,是网站SEO、快速被收录及提高关键词排名的重要手段。本人师从王通学习SEO,王老师强调一定要坚持
- 从个人角度来解析下网络广告中产生的广告主,网站主,广告联盟。联盟包括三要素: 广告主、网站主和广告联盟平台。广告主按照网络广告的实际效果(如
- 一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如:tmux: error while loading sha
- 当制作dedecms模板的head.htm时页面显示正常当制作index.htm模板时发现在index.htm输入中文时会出现乱码之前没有遇
- 1.安装JDK1.1 检查当前虚拟机环境有没有JDK rpm -qa|grep java1.2 卸载 r
- 随着网络的普及、使用互联网的人越来越多,BBS、Blog、IM、SNS、Video等国际上称之为社会化媒体的东西逐渐占领了网民的心,并已深深
- 你是否遭遇过这样的情况?当你在浏览器中输入正确的URL地址,但是打开的并不是你想要去的网站。它可能是114的查询页面,可能是一个广告页面,更
- 俗称“脚本小鬼”的家伙 是属于那种很糟糕的黑客,因为基本上他们中的许多和大多数人都是如此的没有技巧。可以这样说,如果你安装了所有正确的补丁,
- IIS(Internet Information Server,互联网信息服务)是Windows提供的一个Web服务组件,笔者一直Windo
- 前一段时间博主在VMware虚拟机上安装了Ubuntu系统,如果还没有安装的同学可以参考博主上一篇文章:VMware Ubuntu安装详细过
- 我们知道VMware也分几种版本,普通用户最常用的就是Workstation,但是不管使用哪种版本,我们都能发现在安装过程中让我们选择 网络
- 以前自己弄的东西,现在帖出来,希望对大家有点用:)1.1 什么是FTP:文件传输协议原理1.1.1 命令选择1.1.2 命令格式1.2 wu
- Windows 2000 Server安装成功后,一般会启动一个默认的Web站点,为整个网络提供Internet服务。在中小型局域网中,服务
- 事实上,我们一直在谈论的SNS网站并非真正的SNS网站,这些以WebGame来聚拢人气的网站最多只能算是社区——游戏社区,还没有真正上升到S
- 本报讯(记者 敖祥菲) 昨日,在2008百度世界大会的开场发言中,百度公司总裁兼CEO李彦宏用将近一半的演讲篇幅来讲述大洋彼岸充满火药味的总
- 本文实例讲述了Linux环境下Apache开启https服务的方法。分享给大家供大家参考,具体如下:首先申请SSL证书,以阿里云为例,找到域
- 当标题的长度超过限制,就会在后面自动添加 ...可以通过修改下面的文件来取消显示 省略号 分别打开:\module\a