防御SQL注入的方法总结

这篇文章主要讲解了防御SQL注入的方法,介绍了什么是注入,注入的原因是什么,以及如何防御,需要的朋友可以参考下。

SQL注入是一类危害极大的攻击形式。虽然危害很大,但是防御却远远没有XSS那么困难。

SQL注入可以参见:https://en.wikipedia.org/wiki/SQL_injection

SQL注入漏洞存在的原因,就是拼接 SQL 参数。也就是将用于输入的查询参数,直接拼接在 SQL 语句中,导致了SQL 注入漏洞。

1.演示下经典的SQL注入


我们看到:select id,no from user where id=2;

如果该语句是通过sql字符串拼接得到的,比如: String sql = "select id,no from user where id=" + id;

其中的 id 是一个用户输入的参数,那么,如果用户输入的是 2, 那么上面看到查到了一条数据,如果用户输入的是 2 or 1=1 进行sql注入攻击。

那么看到,上面的语句(select id,no from user where id=2 or 1=1;)将user表中的所有记录都查出来了。

这就是典型的sql注入。

再看一列:

我们看到通过 sql 注入能够直接将表 sqlinject 删除掉!可见其危害!

2.sql注入的原因

sql注入的原因,表面上说是因为拼接字符串,构成sql语句,没有使用sql语句预编译,绑定变量造成的。

但是更深层次的原因是将用户输入的字符串,当成了“sql语句”来执行。

比如上面的 String sql = "select id,no from user where id=" + id;

我们希望用户输入的id的值,仅仅作为一个字符串字面值,传入数据库执行,但是当输入了:2 or 1=1 时,其中的 or 1=1 并没有作为 where id= 的字面值,而是作为了 sql语句 来执行的。所以其本质是将用户的输入的数据,作为了命令来执行。

3. sql注入的防御

1> 基本上大家都知道 采用sql语句预编译和绑定变量,是防御sql注入的最佳方法。但是其中的深层次原因就不见得都理解了。

String sql = "select id, no from user where id=?";

PreparedStatement ps = conn.prepareStatement(sql);

ps.setInt(1, id);

ps.executeQuery();

如上所示,就是典型的采用sql语句预编译和绑定变量。为什么这样就可以防止sql 注入呢?

其原因就是:采用了PreparedStatement,就会将sql语句:"select id, no from user where id=?" 预先编译好,也就是SQL引擎会预先进行语法分析,产生语法树,生成执行计划,也就是说,后面你输入的参数,无论你输入的是什么,都不会影响该sql语句的语法结构了,因为语法分析已经完成了,而语法分析主要是分析sql命令,比如 select ,from ,where ,and, or ,order by 等等。所以即使你后面输入了这些sql命令,也不会被当成sql命令来执行了,因为这些sql命令的执行,必须先得通过语法分析,生成执行计划,既然语法分析已经完成,已经预编译过了,那么后面输入的参数,是绝对不可能作为sql命令来执行的,只会被当做字符串字面值参数。所以sql语句预编译可以防御sql注入。

2> 但是不是所有场景都能够采用 sql语句预编译,有一些场景必须的采用字符串拼接的方式,此时,我们严格检查参数的数据类型,还有可以使用一些安全函数,来方式sql注入。

比如 String sql = "select id,no from user where id=" + id;

在接收到用户输入的参数时,我们就严格检查 id,只能是int型。复杂情况可以使用正则表达式来判断。这样也是可以防止sql注入的。

安全函数的使用,比如:

MySQLCodec codec = new MySQLCodec(Mode.STANDARD);

name = ESAPI.encoder().encodeForSQL(codec, name);

String sql = "select id,no from user where name=" + name;

ESAPI.encoder().encodeForSQL(codec, name)

该函数会将 name 中包含的一些特殊字符进行编码,这样 sql 引擎就不会将name中的字符串当成sql命令来进行语法分析了。

实际项目中,一般我们都是采用各种的框架,比如ibatis,mybatis,hibernate等等。他们一般也默认就是sql预编译的。对于ibatis/mybatis,如果使用的是 #{name}形式的,那么就是sql预编译,使用 ${name} 就不是sql预编译的。

以上就是SQL注入防御方法总结,希望对大家之后的学习有所帮助。

美文美图


mysql进阶(二十四)防御SQL注入的方法总结的更多相关文章

  1. mysql进阶(二十九)常用函数

    mysql进阶(二十九)常用函数 一.数学函数 ABS(x) 返回x的绝对值 BIN(x) 返回x的二进制(OCT返回八进制,HEX返回十六进制) CEILING(x) 返回大于x的最小整数值 EXP ...

  2. mysql进阶(二十六)MySQL 索引类型(初学者必看)

    mysql进阶(二十六)MySQL 索引类型(初学者必看)   索引是快速搜索的关键.MySQL 索引的建立对于 MySQL 的高效运行是很重要的.下面介绍几种常见的 MySQL 索引类型.   在数 ...

  3. mysql进阶(二十八)MySQL GRANT REVOKE用法

    mysql进阶(二十八)MySQL GRANT REVOKE用法   MySQL的权限系统围绕着两个概念: 认证->确定用户是否允许连接数据库服务器: 授权->确定用户是否拥有足够的权限执 ...

  4. 使用Typescript重构axios(二十四)——防御XSRF攻击

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  5. 防御SQL注入的方法总结

    这篇文章主要讲解了防御SQL注入的方法,介绍了什么是注入,注入的原因是什么,以及如何防御,需要的朋友可以参考下   SQL 注入是一类危害极大的攻击形式.虽然危害很大,但是防御却远远没有XSS那么困难 ...

  6. 十四:SQL注入之类型及提交注入

    简要明确参数类型 数字,字符,搜索,json等 简要明确请求方法 GET,POST,COOKIE,REQUEST,HTTP头 其中SQL语句干扰符号:' " % ) } 等,具体查看用法 非 ...

  7. mysql进阶(二十五)解决数据库NO CONNECTION问题

    解决数据库NO CONNECTION问题 前言 数据库版本类型:Mysql5.5 在应用程序连接数据库时,提示数据库连接失败.打开数据库查看,显示如下. 究其原因,是因为mysql服务出现了问题,重启 ...

  8. mysql进阶(二十二)MySQL错误之Incorrect string value: '\xE7\x81\xAB\xE7\x8B\x90...中文字符输入错误

    MySQL错误之Incorrect string value: '\xE7\x81\xAB\xE7\x8B\x90...' for column 'tout' at row 1中文字符输入错误 在实验 ...

  9. mysql进阶(二十)CPU超负荷异常情况

    CPU超负荷异常情况 问题 项目部署阶段,提交订单时总是出现cpu超负荷工作情况,导致机器卡死,订单提交失败.通过任务管理器可见下图所示: 通过任务管理器中进程信息(见下图)进行查看,可见正是由于项目 ...

随机推荐

  1. KMP算法小结

    最近看了一些关于KMP算法的资料,在此写一篇博客总计一下. 1.KMP算法介绍 KMP算法是一种字符串搜索的改进算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称 ...

  2. JS的事件模型

    之前对事件模型还是比较清楚的,许多概念都清晰映射在脑海中.工作之后,一方面使用的局限性,二是习惯于用框架中的各种事件监听方式,简单即方便,久而久之,事件的一些概念开始淡出记忆中,就像我现在已经开始淡忘 ...

  3. SpringMVC注解@Component、@Repository、@Service、@Controller区别

    SpringMVC中四个基本注解: @Component.@Repository   @Service.@Controller 看字面含义,很容易却别出其中三个: @Controller   控制层, ...

  4. C# 基础问答

    1.静态变量和非静态变量的区别? 2.const 和 static readonly 区别? 3.extern 是什么意思? 4.abstract 是什么意思? 5.internal 修饰符起什么作用 ...

  5. python学习之路网络编程篇(第二篇)

    新课程知识的引入:python作用域 #python中无块级别作用域 if 1 == 1 : name = 'alex' print(name) for i in range(10): name = ...

  6. ACM 排列2

    Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数.  Input每组数据占一行,代表四张卡片上的数字(0<=数字<=9 ...

  7. Docker 移除镜像

    如果要移除本地的镜像,可以使用 docker rmi 命令.注意 docker rm 命令是移除容器. $ sudo docker rmi training/sinatra Untagged: tra ...

  8. 弹出层之2:JQuery.BlockUI

    JQuery.BlockUI是众多JQuery插件弹出层中的一个,它小巧(原版16k,压缩后10左右),容易使用, 功能齐全,支持Iframe,支持Modal,可定制性高也意味他默认谦虚的外表. jQ ...

  9. hexo常用命令

    Hexo 约有二十个命令,但普通用户经常使用的只有下列几个: hexo s hexo s是hexo server的缩写,命令效果一致:启动本地服务器,用于预览主题.默认地址: http://local ...

  10. Ubuntu等Linux系统显卡性能测试软件 Unigine 3D

    Ubuntu等Linux系统显卡性能测试软件 Unigine 3D Ubuntu Intel显卡驱动安装,请参考: http://blog.csdn.net/zhangrelay/article/de ...