SQL注入的本质

SQL注入的实质就是通过SQL拼接字符串追加命令,导致SQL的语义发生了变化。为什么发生了改变呢? 因为没有重用以前的执行计划,而是对注入后的SQL语句重新编译,然后重新执行了语法解析。 所以要保证SQL语义不变,(即想要表达SQL本身的语义,并不是注入后的语义)就必须保证执行计划确定不被改变。
 
SQL注入的表现
 示例
1.我们先熟悉一下表里的东西
 

2.要查询的原SQL语句。

3.注入的SQL语句

分析示例:
原SQL语句
select COUNT(*) from T_Users where UserName  = 'a' and Password  ='b'1

语义:要查找(用户名为‘a’,密码为‘b’) 的用户总共有几个.  查询结果为1

注入后的SQL语句
select COUNT(*) from T_Users where UserName  = 'a' and Password  = 'b' or 1=1 --'1

注入后的语义:查找 (密码是a的,并且用户名是b的,) 或者1=1 的所有用户的数量。 这时候语义发生了改变,查询结果为4

分析:如果用户在输入密码时, 输入的不是b    而是b’ or 1=1- -  ,语义将会发生改变,(- -在数据库中是注释的标记)最后查询的结果当然也就不相同了。原语句的查询结果为1,注入后的查询结果为4。
SQL注入的危害
我们刚刚示范了SQL注入带来的查询结果的改变,这个可能会让别有用心的用户熟知我们数据库中的记录条数。或者如果输入的是b’ delect T_Users - -  这时候我们整张表都被删除了,这个带来的后果可想而知。
防止SQL注入–参数化查询
我们的机房重构中D层一直在用参数化查询,但是我当时没有完全理解用参数化查询的用意。直到现在才理解了为什么要用参数化查询和参数化查询如何防止SQL注入的。
public int checkUser(Users user)
{
string sql = "select COUNT(*) from T_Users where UserName = @UserName and Password = @Password";
SqlParameter[] paras ={new SqlParameter ("@UserName",User.username) ,
new SqlParameter ("@Password",User.password)};
int num = sqlhelper.ExecuteNonQuery(sql, paras);
return num ;
}12345678

这是我们用了参数化查询后的效果,我们来分析一下参数化查询是如何防止sql注入的。

select count(*) from T_Users where UserName = ‘a’ and Password = ‘b’ or 1=1- -‘,
是等到 UserName 参数传过来,才会去编译这条 sql语句(sql语句是编译后执行的),而这个时候, 这个拼接的sql 多了 or 选项,这改变了sql语句的本意。
参数化查询:是先编译 这样一条sql,   select count (*) from T_Users where = UserName = @UserName and Password = @Password ,和函数的编译一样, 这样的话,以后’b’ or 1=1- - ’  只能作为 Password  的参数了,,,相当于你去查  ” ‘b’ or 1=1—’   ” 这个密码,而不是 查  “b” 这个密码 或者 ” 1=1 ” 了。 相当于把 or 给屏蔽掉了。or 原来是sql的一项(普通的拼接),现在就是个普通字符串参数(参数化查询)
,不能改变sql语义,也不能改变编译执行计划,所以防止了SQL注入。
 
示例小结:
正常的命令是程序中的“常量”,能动手脚的只能是可输入的用户名、密码这些可输入的“变量”。 拼接方式是将常量、变量拼在一起编译,才可以在正常的命令后追加命令。参数化的方式仅常量参与编译,就无法追加命令,防止了sql注入。
总结:
参数化查询的方式简单来说就是指用参数参与编译,这样就全是常量了,编译执行计划时没有用到参数,所以命令是确定的。编译后计划便确定了,编译后传参数知识为了运行执行计划,执行计划不变,就不会多出命令,SQL语义就无法改变,防止了sql注入。

SQL注入与参数化查询的更多相关文章

  1. 防止sql注入的参数化查询

    参数化查询为什么能够防止SQL注入 http://netsecurity.51cto.com/art/201301/377209.htm OleDbDataAdapter Class http://m ...

  2. 多条件搜索问题 -sql拼接与参数化查询

    来源:传智播客  免费开发视频. 问题:根据书名或出版社或作者查询书籍信息. using System; using System.Collections.Generic问题; using Syste ...

  3. 利用DNS实现SQL注入带外查询(OOB)

    根据用于数据检索的传输信道,SQLi可分为三个独立的类别:inference(经典SQL注入),inband(盲注.推理注入.带内注入)和out-of-band 一.什么是OOB out-of-ban ...

  4. Sql Server 的参数化查询

    为什么要使用参数化查询呢?参数化查询写起来看起来都麻烦,还不如用拼接sql语句来的方便快捷.当然,拼接sql语句执行查询虽然看起来方便简洁,其实不然.远没有参数化查询来的安全和快捷. 今天刚好了解了一 ...

  5. SQL注入:基本查询原理

    SQL注入概述 sql注入不需要精通sql的各种命令,只需要了解几个命令并会使用即可. SQL注入:一种针对于数据库的攻击 现在的web网站都需要数据库的支持. SQL部分重要内容: 库:databa ...

  6. python之MySQL学习——防止SQL注入(参数化处理)

    import pymysql as ps # 打开数据库连接 db = ps.connect(host=', database='test', charset='utf8') # 创建一个游标对象 c ...

  7. 从sp_executesql中返回table型数据及动态SQL语句的参数化查询

    在返回分页数据时,我们会经常会用到参数化传递过滤条件,如何拼接SQL语句成了一个难题. 我们可以这样拼接: exec('sp_executesql sql语句,参数定义,参数值') sql语句和参数定 ...

  8. sql注入之双查询注入

    双查询注入前需要了解什么是子查询 子查询可以理解在一个select语句中再插入一个select 里面的select语句就是子查询 例子:select concat((select database() ...

  9. 对于SQL注入的理解

    从网上搜索的资料,结合自己的理解整理了一下,网友们在查看时若有发现问题,还请不吝指正,谢谢! 1.什么是SQL注入? ——官方说法:把SQL命令插入到web表单验证的输入框中,提交到服务器,以达到越过 ...

随机推荐

  1. certbot 获取数字证书失效问题

    title: certbot 获取数字证书失效问题 author: Narule date: 2021-02-18 10:45:00 +0800 categories: [Technology^技术, ...

  2. The Weekly Web Dev Challenge: Emoji Ratings

    The Weekly Web Dev Challenge: Emoji Ratings /* DESCRIPTION: You job is to enable users to give a rat ...

  3. Contributor License Agreement

    Contributor License Agreement CLA https://cla.js.foundation/lodash/lodash?pullRequest=4756 https://g ...

  4. 聚焦 2021 NGK 新加坡区块链技术峰会,探讨DeFi未来新生态!

    2021年1月31日14时,备受行业关注的"2021 NGK 新加坡区块链技术峰会"如期举行.本次峰会由NGK官方主办,以"DeFi"为主题,探讨了区块链技术革 ...

  5. 数据库范式(1NF/2NF/3NF)

    本文转载自数据库范式(1NF/2NF/3NF) 概述 范式:英文名称是 Normal Form,它是英国人 E.F.Codd(关系数据库的老祖宗)在上个世纪70年代提出关系数据库模型后总结出来的,范式 ...

  6. js 表格插入指定行

    js在table指定tr行上或下面添加tr行 function onAddTR(trIndex)         {             var tb = document.getElementB ...

  7. 五大自动化测试的Python框架

    1.Robot Framework 作为最重要的Python测试框架之一,Robot Framework主要被用在测试驱动(test-driven)类型的开发与验收中.虽然是由Python开发而来,但 ...

  8. Java基础语法:标识符

    Java所有的组成部分都需要名字. 类名.变量名 以及方法名 都被称为标识符. 一.规则 Ⅰ.首字符 规则:所有的标识符都应该以字母(A-Z 或者 a-z).美元符($).下划线(_)开始. 示例:t ...

  9. 使用gitlab构建基于docker的持续集成(三)

    使用gitlab构建基于docker的持续集成(三) gitlab docker aspnetcore 持续集成 构建发布思路: aspnetcore 下的dockerfile编写 发布docker- ...

  10. Android Layout属性

    通用属性 android:layout_height android:layout_width 值 含义 fill_parent/match_parent 高度或者宽度对齐到父控件 wrap_cont ...