BOSS:你连什么是 SQL 注入都不知道,我怎么给你加薪?

1 什么是 SQL 注入?

所谓 SQL 注入,便是指黑客将 SQL 代码嵌入在输入参数之中,在未经过滤的情况下直接拼接到 SQL 语句之中进行解析并执行的一种攻击方法。

2 一个 SQL 注入的简单例子

我们来模拟一个登录场景,大家平时登录网站什么之类的需要啥呢?没错,账号密码!于是,我们的登录界面一般都是这个样子。。。

很明显,
当我们输入账号密码按下回车之后,会向后台返回账号密码两个参数。

https://mail.qq.com?username=3030&password=1010

然后在后台相当于调用了下面的 SQL 语句:

SELECT * FROM user WHERE username = '3030' AND password = '1010'

好,上面老实人一般都会正常输入账号密码,但总是有一些不法分子存在非分之想,他们会这么输入账号密码:

在这里插入图片描述
在后台,执行的 SQL 语句变成了下面这条:

SELECT * FROM user WHERE username = '3030'#' AND password = '1010'

在 MySQL 中,# 之后的所有字符串都会被当成注释进行处理,其实上面的 SQL 语句与下面这一条等价:

SELECT * FROM user WHERE username = '3030'

我们可以发现,只需要在账号后面加上 '# 两个字符,然后我们便可以随便输入密码,因为最终会被注释掉。在这种情况下,我们只需要知道别人的账号,即可不需要密码进行登录操作,这是一个非常严重的安全问题!

3 SQL 注入的条件

经过一个例子,我们来总结一下 SQL 注入的产生条件:

  1. 存在参数传递
  2. 参数值带入 SQL 语句查询并且执行

4 如何防止 SQL 注入攻击?

在上面的例子中我们可以发现,SQL 注入攻击实在太可怕了!那么,我们又该如何防止 SQL 注入攻击呢?一般我们可以采取以下方法:

  1. 对输入变量的类型与格式进行检查。如果参数类型为整数,则加上必要的判断;如果参数类型为字符串,则使用正则表达式进行过滤操作(账号必须为 [0-9a-zA-Z] 范围内的字符串)
  2. 对特殊字符进行过滤和转义。例如对 ’ 或 " 或 \ 等特殊字符进行转义
  3. 使用 MySQL 的预编译机制

什么是预编译?

一般 SQL 语句的执行可以分为以下三个过程:

  1. 词法和语义解析
  2. 优化 SQL 语句,制定执行计划
  3. 执行并返回结果

这种是一般情况,但是我们在某些场景下可能存在 SQL 语句反复执行或者每次执行只有个别值不同的情况,如果每次执行都要重新经过上面三个步骤,显然效率是非常不可观的,幸好预编译机制可以有效解决这个问题。

预编译机制将 SQL 语句中的值用占位符替代,可以理解为将 SQL 语句模板化或者参数化。使用预编译,我们便可以一次编译、多次运行,省去了解析,优化等过程,另外使用预编译机制也可以有效防止 SQL 注入。

问题来了,为什么预编译机制可以防止 SQL 注入呢?使用预编译机制,我们后台的 SQL 语句就可以抽象为:

SELECT * FROM user WHERE username = ? AND password = ?

在该语句中,无论用户输入何种账号密码,逻辑关系始终为 AND,不会导致 SQL 语句结构发生变化。参数值是参数值,语句是语句,参数的值并不是语句的一部分,MySQL 只按语句的语义来执行 SQL。

5 Mybatis 如何防止 SQL 注入?

MyBatis 是我们常用的持久层框架,其 SQL 均需要我们手动编写,那么它又是如何防止 SQL 注入的呢?

在编写映射语句时,使用 #{} 会进行预编译处理,其 SQL 语句类似于下面的格式:

SELECT * FROM user WHERE username = ? AND password = ?

SQL 执行时,会直接将占位符 ?替换为参数,自然不会存在 SQL 注入的问题。

参考:SQL注入攻击常见方式及测试方法
SQL注入详解

发布了135 篇原创文章 · 获赞 266 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Geffin/article/details/104935639