ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
##SQL注入简介: 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。 ## SQL注入方法: ### 一、拼接字符串(通过输入框输入SQL语句使其改变原意) `Select * from T_User where UserID =’txtUserID.Text’andPassword=’ txtPassword.Text ’ ` 其原理是通过查找T_User 表中的用户名(UserID) 和密码(Password) 的结果来进行授权访问, 在txtUserID.Text为mysql,txtPassword.Text为mary,那么SQL查询语句就为: Select * from users where username =’ mysql ’ and  password  =’ mary ’ 如果分别给txtUserID.Text 和txtPassword.Text赋值’ or ‘1’ = ‘1’ --和abc。那么,SQL 脚本解释器中的上述语句就会变为: Select * from T_User  where UserID =’’or  ‘1’ = ‘1’  -- and Password =’abc’ 该语句中进行了两个条件判断,只要一个条件成立,就会执行成功。而'1'='1'在逻辑判断上是恒成立的,后面的"--" 表示注释,即后面所有的语句为注释语句这样我们就成功登录。即SQL注入成功. 原来SQL语句:`insert  into  category(name)  values(‘”+caName+”’) ` 输入框中输入`:caName=娱乐新闻’)select category --‘) ` SQL语句变成:`insert  into  category(name) values(‘娱乐新闻’)Select  category  --‘) ` SQL语句改变后,将执行插入和查询两个操作(如果修改的不是查询而是删除将会更加可怕),即SQL注入成功。 ###二、查看错误页信息(SQL Server有一些系统变量,如果我们没有限制错误信息的输出,那么注入着可以直接从出错信息获取) Web中的网址:http://www.xxx.com/Login.aspx?id=49 and user>0首先,前面的语句是正常的,重点在and user>0,我们知道,user是SQL Server的一个内置变量,它的值是当前连接的用户名 ,类型为nvarchar。拿一个nvarchar的值跟int的数0比较,系统会先试图将nvarchar的值转成int型,当然,转的过程中肯定会出错,SQL Server的出错提示是:将nvarchar值 ”abc” 转换数据类型 为 int 的列时发生语法错误,abc正是变量user的值,这样,注入着就拿到了数据库的用户名,即SQL注入成功。 ## SQL注入防范: ### 一、简单防范: 1.输入框中限制特殊字符以及长度 2.Web中设置错误提示页即: 在Web.Config文件中设置 ~~~ <!--出现错误的时候自动导向("~/error.html"是弹出页面的路径)-->           <customErrors mode="On" defaultRedirect ="~/error.html" ></customErrors> ~~~ 3.URL重写: URL重写就是首先获得一个进入的URL请求然后把它重新写成网站可以处理的另一个URL的过程。举个例子来说,如果通过浏览器进来的URL是“UserProfile.aspx?ID=1”那么它可以被重写成“UserProfile/1.aspx” ### 二、SQL语句中的防范 1.参数化查询:参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值。 例如: 不使用参数化查询: `string sql = "select * from comment where newsId = "txtnewsId" order by createTime desc"; ` 因为上面SQL语句中的"txtnewsId"是不确定的,每次调用的时候需要将SQL语句重新编译,这就能用上面的拼接字符串实现SQL注入。 使用参数化查询: ~~~ string sql = "select * from comment where newsId = @newsId order by createTime desc"; SqlParameter[] paras = new SqlParameter[]{new SqlParameter ("@newsId",newsId)}; ~~~ 因为上面SQL语句是固定的,调用的时候只需要将@newsId的值传上去就可以,所以即便用户输入任何信息也会当成一个值传递进去,防止SQL注入。 2.通过写存储过程: 其实在存储过程里面也需要用到参数化查询并且存储过程本身没有SQL注入这两点同时满足才能防止SQL注入。 3.限制数据库的访问权限: 设立不同用户的特殊权限,例如:用户名为1的用户只允许查询操作,然而用户1的信息被盗取登陆之后就不能对表进行别的操作,这样就一定程度上保证了数据的安全性。