flash网站后台,上海网站改版,flask网站开发源码,深圳市建设厅官方网站前言
防范SQL注入攻击是每一位做后端开发的程序员必须会的基本功。本文介绍其中一种防范攻击的方法#xff1a;SQL预编译。 本文大部分内容引用自这篇文章#xff0c;部分内容有修改。 注入例子
先简单回顾下SQL注入攻击的过程#xff0c;假设有一个SQL语句#xff1a;
…前言
防范SQL注入攻击是每一位做后端开发的程序员必须会的基本功。本文介绍其中一种防范攻击的方法SQL预编译。 本文大部分内容引用自这篇文章部分内容有修改。 注入例子
先简单回顾下SQL注入攻击的过程假设有一个SQL语句
SELECT * FROM users WHERE id {$p};{$p}是用户传递过来的查询参数假设用户传递的参数是123则SQL会是
SELECT * FROM users WHERE id 123;但如果用户传递的参数是;DROP TABLE users;-- SQL就会变成
SELECT * FROM users WHERE id ;DROP TABLE users;-- ;原本一个简单的SELECT语句通过精心构造查询参数就让它变成了一个删除users表的语句
从注入的过程可以发现如果用户传递过来的参数我们不做任何处理就拼接到SQL语句中很容易就会让黑客改变我们SQL语句的语法结构引发严重事故。
解决方法
一、对用户参数进行转义
对一些有特殊意义的字符例如单引号进行转义转义后再去数据库查询相信很多人都知道这种做法本文就不详细讲了。
二、SQL预编译 本文说的预编译是指在数据库端进行的预编译。有部分代码库的预编译是在客户端本地进行的这种是虚假的“预编译”。 通过SQL预编译可以防止语法结构被改变。先了解下SQL的执行过程
词法分析将SQL语句分解成一个个token关键字、标识符、运算符然后对token进行分类和解析生成相应的数据结构。语法分析根据SQL语法检测规则检查语法是否正确并成成语法树。语义分析遍历语法树确定表和列等信息同时检查语义的正确性。优化处理使用优化器对SQL语句进行处理和优化比如执行计划、索引等。执行计划使用执行计划生成器生成SQL语句的执行计划比如数据的访问方式索引的使用方式等。引擎执行将执行计划发送给相应的数据库引擎进行处理执行计划被翻译成底层的操作指令执行数据扫描、索引查找、排序、分组等操作。返回数据将执行结果返回给客户端比如查询结果集或操作结果。
在这里我们粗暴的把执行过程理解成两步即先编译SQL语法结构1~3步再执行SQL语句4~7步。
正常情况下用户输入的参数会直接参与SQL语法的编译而预编译则是先构建语法树确定SQL语法结构以后再拼接用户的参数。
2.1 预编译原理
预编译最初的目的是提高SQL语句的执行效率因为有很多语法结构相同但只有参数值不同的SQL比如
SELECT * FROM users WHERE id 1;
SELECT * FROM users WHERE id 2;这些SQL的语法树相同但每次都要进行重复的编译很浪费时间。
而预编译可以将SQL语句模板化值的位置用占位符替代这样数据库就会事先编译好SQL语法结构等真正调用的时候再传入参数值执行省掉了重复建立语法树的时间。
SELECT * FROM users WHERE id {占位符}因为语法树已经建立好了要查询什么表、查询字段是哪些、有多少个查询条件等等这些全都已经确定好了用户传入的参数不参与语法树的构建就改不了SQL的语法结构也就避免了注入。
2.2 预编译的局限性
预编译的机制是先编译再传值用户传递的参数无法改变SQL语法结构从根本上解决了SQL注入的问题。
但并不是所有参数都可以使用预编译比如动态表名和列名的场景因为语义分析时会解析语法树检查表名和列名是否存在所以表名和列名不能被占位符替代也就无法使用预编译。
同理排序场景的ASC/DESC也不能使用预编译。
参阅
预编译为什么能防止SQL注入一看你就明白了。预编译原理详解预编译SQL为什么能够防止SQL注入