参数化查询原理

2019-12-26  本文已影响0人  我叫397

1.参数化查询原理

参数化查询是指在设计与数据库链接并访问时,在需要数值或数据的地方,使用参数来给值。即在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中有恶意的指令,由于已经编译完成,就不会被数据库运行。目前,参数化查询是最有效可预防SQL注入攻击的的防御方法

2.防SQL注入

参数化查询的作用主要有两点:

(1)参数过滤

(2)执行计划重用

防止SQL注入主要就是利用了执行计划重用,即在链接数据库时给参数赋值时,重用了以前的执行计划,没有对SQL语句重新编译,也就没有重新执行语法解析,所以语句还是原来的结构,符合标准,只是用一个具体的值替换参数

以SQL Server为例,数据库接收到一句SQL指令做作的工作如下:

收到指令-->编译SQL生成执行计划-->选择执行计划-->执行执行计划

当SQL Server收到任何一个指令,包括:查询、批处理、存储过程、触发器、预编译指令和动态SQL Server语句,要完成语法解析、语义分析,然后再进行“编译”,生成能够运行的“执行计划”。在编译的过程中,SQL Server 会根据所涉及的对象的架构、统计信息,以及指令的具体内容,估算可能的执行计划,以及它们的成本,最后选择一个SQL Server认为成本最低的语句

执行计划生成之后,SQL Server通常会把它们缓存到内存里,术语统称它们叫“Plane Cache”。以后同样的语句执行,SQL Server就可以使用同样的执行计划,而无须再做一次编译。这种行为,叫做“重用”。但是有时候,哪怕是一模一样的语句,SQL Server下次执行还是要再做一次编译。这种行为叫“重编译”。执行计划的编译和重编译都是要耗费资源的

3.实例

原始SQL:

SELECT COUNT(*) FROM USERS WHERE PASSWORD = 'A' AND USERNAME = 'B'

结果:

原始SQL执行结果

注入SQL:

这里有人将UserName设置为了"b' or 1=1 –"

SELECT COUNT(*) FROM USERS WHERE PASSWORD = 'A' AND USERNAME = 'B' OR 1=1—'

结果:

注入SQL执行结果

任何动态的执行SQL都有注入的风险,因为动态意味着不重用执行计划,而如果不重用执行计划的话,那么就基本上无法保证你写的SQL所表示的意思就是你要表达的意思

这就好像小时候的填空题,查找密码是(____) 并且用户名是(____)的用户,不管你填的是什么值,我所表达的就是这个意思, 存储过程也是一样的道理,因为可以重用执行计划

参考:

https://blog.csdn.net/wrs120/article/details/54924763

https://blog.csdn.net/andong154564667/article/details/81117616

上一篇 下一篇

猜你喜欢

热点阅读