# SQL注入

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。 [1] 比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击

# 关系型数据库

  • 存储结构化数据
  • 可高效操作大量数据
  • 方便处理数据之间的关联关系
  • 常见的关系型数据库:MySQL,Oracle,SQLServer,PostGreSQL

# SQL语言

  • 结构化查询语言,一种描述性语言,面向语义化
  • SQL语言的作用:对存储在RDBMS(关系型数据库管理系统)中的数据进行增删改查等操作,有些非关系数据库也支持SQL

# SQL注入原理

SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

# SQL注入类型

根据相关技术原理,SQL注入可以分为平台层注入代码层注入。前者由不安全的数据库配置或数据库平台的漏洞所致;后者主要是由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。

# SQL注入产生原因

  • 不当的类型处理;
  • 不安全的数据库配置;
  • 不合理的查询集处理;
  • 不当的错误处理;
  • 转义字符处理不合适;
  • 多个提交处理不当。

# SQL注入示例

//查询语句
SELECT * FROM table WHERE id=${id}
//注入数据
1 or 1=1
//注入后的查询语句
SELECT * FROM table WHERE id=1 or 1=1

//查询语句
SELECT * FROM user WHERE username=`${username}` AND password=`${password}`
//注入数据
1' or '1'='1
//注入后的查询语句
SELECT * FROM user WHERE username=`123` AND password=1' or '1'='1'

SQL注入示例

# SQL注入危害

  • 猜解密码
  • 获取数据
  • 删库删表
  • 拖库

# SQL注入防御

  • 永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双"-"进行转换等
  • 永远不要使用动态拼装SQL,可以使用参数化的SQL或者直接使用存储过程进行数据查询存取
  • 永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接
  • 不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息
  • 应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装,把异常信息存放在独立的表中
  • 使用ORM(对象关系映射)

# 参数化查询

参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,这个方法目前已被视为最有效可预防SQL注入攻击 (SQL Injection) 的攻击手法的防御方式

# 参数化查询原理

在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成 SQL 指令的编译后,才套用参数运行,因此就算参数中含有恶意的指令,由于已经编译完成,就不会被数据库所运行。 有部份的开发人员可能会认为使用参数化查询,会让程序更不好维护,或者在实现部份功能上会非常不便,然而,使用参数化查询造成的额外开发成本,通常都远低于因为SQL注入攻击漏洞被发现而遭受攻击,所造成的重大损失

# SQL 指令撰写方法

MySQL 的参数格式是以 "?" 字符加上参数名称而成

UPDATE myTable SET c1 = ?c1, c2 = ?c2, c3 = ?c3 WHERE c4 = ?c4

//执行sql查询
query(`SELECT * FROM user WHERE id=?`,[id])

# NOSQL注入防御

  • 检测数据类型
  • 类型转换
  • 写完整条件
更新时间: 5/13/2020, 11:23:00 PM