sql防注入总结
如何预防SQL注入?
1. 严格限制Web应用的数据库的操作权限,给此用户提供仅仅能满足其工作的最低权限, 从而最大限度的减少注入攻击对数据库的危害
2. 检查输入的数据是否具有所期望的数据格式,严格限制变量的类型,例如使用regexp
包进行一些匹配处理,或者使用strconv包对字符串转化成其它基本类型的数据进行判 断
3. 对进入数据库的特殊字符('”\尖括号&*;等)进行转义处理,或编码转换
4. 所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是 将用户输入变量嵌入到SQL语句中,即不要直接拼接SQL语句。例如使用database/sql 里面的查询函数Prepare和Query,或者Exec(query string, args ...interface{} )
5. 在应用发布之前建议使用专业的SQL注入检测工具进行检测,以及时修补被发现的SQL 注入漏洞。网上有好多这方面的开源工具,例如sqlmap、SQLninja等
6. 避免网站打印出SQL错误信息,比如类型错误、字段不匹配等,把代码里的SQL语句 暴露出来,以防止攻击者利用这些错误信息进行SQL注入
数据库内部处理:如何解析SQL语句并如何生成执行计划?
1. 解析
step1: 检查共享池中是否有之前解析相同的SQL语句所存储的SQL文本,解析树和 执行计划。如果能找到对应的执行计划,直接从缓存中得到之前所产生的执行 计划。从而跳转到(2. 参数绑定)或(3. 执行)
step2: 语法分析,判断是否符合规范
step3: 检查语句涉及的数据库对象是否存在,且用户是否具有权限
step4: 视图转换和表达式转换
step5: 决定最佳执行计划
step6: 将SQL文本,解析树,执行计划缓存
2. 参数绑定
如果SQL语句使用了绑定变量,给绑定变量赋值,将该变量值带入执行计划
3. 执行
4. 返回结果
预编译方式的过程:
1. 将含有占位符的sql语句发送给数据库管理系统
2. 数据库管理系统解析,编译,优化,将最终的执行结果缓存
3. 参数绑定
4. 执行
5. 返回结果
优点:
1. 一次编译,多次执行(每次与数据库交互时,执行语句相同,只是参数绑定不同)
2. 防止sql注入(绑定的参数仅仅作为参数处理,不会成为mysql执行语句)
3. 预编译sql操作意味着数据库系统不用再进行分析,直接从缓存中取出执行计划执行即 可,提高效率
不采用预编译与采用预编译两种方式区别:
不采用预编译:将sql拼装起来发送给数据库,只交互一次
采用预编译:第一次交互先将sql语句预编译,第二次交互是在sql语句执行时发送绑定参数
防SQL注入整体思路:
使用正则表达式对常见sql注入检测+过滤sql关键字+参数转义+预编译
1.常见sql注入检测+过滤sql关键字+参数转义(结合mysql源码mysql_escape_string函数)编写主要代码:
2. 本地测试参数绑定(预编译)的方式是否能防止sql注入
(1)本地创建approve数据库,并在user表添加两条记录:
(2)本地测试主要代码:
(3)字符串拼接的方式测试结果:打印所有数据,存在sql注入问题
(4)使用占位符测试结果:未查询到任何记录,防止sql注入
测试结果:
使用占位符(参数绑定,预编译)的方式操作数据库,绑定的参数仅仅作为参数处理,不会成为mysql执行语句,能够防止sql注入