转自维基百科:

SQL注入是一种代码注入技术,用于攻击数据驱动的应用程序,在这种应用程序中,恶意的SQL语句被插入输入字段中执行(例如将数据库内容转储给攻击者)。[1] SQL注入必须利用应用程序软件中的安全漏洞,例如,当用户输入被错误地过滤为嵌入在SQL语句中的字符串文字 转义字符,或者用户输入没有强类型和意外执行时。SQL注入通常被称为网站的攻击媒介,但可以用来攻击任何类型的SQL数据库。

SQL注入攻击允许攻击者欺骗身份,篡改现有数据,导致拒绝问题,如排除交易或更改余额,允许完整披露系统上的所有数据,破坏数据或使其不可用,并成为数据库服务器

在2012年的一项研究中,观察到平均每个月的网络应用程序收到4次攻击活动,零售商受到的攻击是其他行业的两倍。

SQL注入(SQLI)被Open Web应用程序安全项目认为是2007年和2010年排名前10的Web应用程序漏洞之一。[5] 2013年,SQLI被评为OWASP前十名的头号攻击。[6] SQL注入有四个主要的子类:

风暴蠕虫是复合SQLI的一种表示。[11]

这个分类代表了SQLI的状态,尊重它的发展到2010年 - 进一步的改进正在进行。[12]

技术实现[ 编辑]

错误地过滤了转义字符[ 编辑]

当用户输入不是针对转义字符进行筛选,然后传递给SQL语句时,会发生这种SQL注入形式。这导致了应用程序的最终用户对数据库执行的语句的潜在操纵。

以下代码行说明了此漏洞:

statement =“ ”+ userName +“ ”
SELECT * FROM users WHERE name = '';

此SQL代码旨在从其用户表中提取指定用户名的记录。但是,如果“userName”变量是由恶意用户以特定方式制作的,那么SQL语句可能比代码作者所期望的要多。例如,将“userName”变量设置为:

'或'1'='1

或者使用注释甚至阻塞查询的其余部分(有三种类型的SQL注释[13])。所有三条线在最后都有一个空格:

'OR'1'='1' -
'或'1'='1'({
'或'1'='1'/ *

以父语言呈现下列SQL语句之一:

SELECT  *  FROM  users  WHERE  name  =  ''  OR'1  ' = '1' ;
SELECT  *  FROM  users  WHERE  name  =  ''  OR'1  ' = '1'  - ';

如果在验证过程中使用此代码,则可以使用此示例强制从所有用户中选择每个数据字段(*),而不是从编码人员希望的一个特定用户名中选择,因为评估“1” =“1”始终为真(短路评估)。

下面的语句“username”的下列值将导致“用户”表中删除,以及从“用户信息”表中的所有数据的选择(本质上揭示了每个用户的信息),其使用API是允许多个语句:

一个';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't

这个输入呈现如下并指定的最终SQL语句:

SELECT  *  FROM  users  WHERE  name  =  'a' ; DROP  TABLE  用户;  SELECT  *  FROM  userinfo的 WHERE  'T'  =  'T' ;

尽管大多数SQL服务器实现允许以这种方式一次调用多个语句,但是由于安全原因,一些SQL API(如PHPmysql_query()函数)不允许这样做。这可以防止攻击者注入完全独立的查询,但不会阻止他们修改查询。

类型处理不正确[ 编辑]

用户提供的字段没有强类型或未检查类型约束时,就会发生这种SQL注入形式。当在SQL语句中使用数字字段时,可能会发生这种情况,但是程序员不进行检查来验证用户提供的输入是否为数字。例如:

声明:=“ ”+ a_variable +“;”
SELECT * FROM userinfo WHERE id =

从这个陈述中可以清楚地看到,作者希望变量是一个与“id”字段相关的数字。但是,如果它实际上是一个字符串,那么最终用户可以按照他们的选择操作语句,从而绕过了对转义字符的需要。例如,设置a_variable为

1; DROP TABLE用户

将从数据库中删除(删除)“users”表,因为SQL变成:

SELECT  *  FROM  userinfo  WHERE  id = 1 ;  DROP  TABLE  用户;

盲目SQL注入[ 编辑]

当Web应用程序容易受到SQL注入的攻击,但注入的结果对攻击者不可见时,将使用Blind SQL Injection。带有此漏洞的页面可能不是显示数据的页面,而是根据注入到为该页面调用的合法SQL语句中的逻辑语句的结果显示不同。这种类型的攻击传统上被认为是时间密集型的,因为需要为恢复的每一位创建新的语句,并且根据其结构,攻击可能包含许多不成功的请求。最近的进步已经允许每个请求恢复多个位,没有不成功的请求,允许更一致和有效的提取。[14]一旦漏洞的位置和目标信息已经建立,有几种工具可以自动执行这些攻击。[15]

有条件的回应[ 编辑]

一种类型的盲注入强制数据库在普通应用程序屏幕上评估逻辑语句。作为示例,书评网站使用查询字符串来确定要显示的书评。所以URL http://books.example.com/showReview.php?ID=5会导致服务器运行查询

SELECT  *  FROM  bookreviews  WHERE  ID  =  'Value(ID)' ;

从其中将填充评论页面,其中来自具有ID 5 的评论的数据存储在表格书籍视图中。查询完全发生在服务器上; 用户不知道数据库,表或字段的名称,用户也不知道查询字符串。用户只能看到上面的URL返回书评。甲黑客可以加载的URL 和,这可能导致在查询http://books.example.com/showReview.php?ID=5 OR 1=1http://books.example.com/showReview.php?ID=5 AND 1=2

SELECT  *  FROM  bookreviews  WHERE  ID  =  '5'  或 '1' = '1' ;
SELECT * FROM bookreviews WHERE ID = '5' 和 '1' = '2' ;

分别。如果使用“1 = 1”URL加载原始评论,并且从“1 = 2”URL返回空白或错误​​页面,并且尚未创建返回的页面以提醒用户输入无效,或者其他单词已被输入测试脚本捕获,该网站可能容易受到SQL注入攻击,因为在这两种情况下,查询可能已成功通过。黑客可能会继续使用这个查询字符串来显示在服务器上运行的MySQL的版本号,它将在运行MySQL 4的服务器上显示书评,否则将显示一个空白或错误​​页面。黑客可以继续使用查询字符串中的代码来从服务器收集更多信息,直到发现另一个攻击途径或达到他或她的目标。http://books.example.com/showReview.php?ID=5 AND substring(@@version, 1, INSTR(@@version, '.') - 1)=4[17]

二阶SQL注入[ 编辑]

当提交的值包含存储而不是立即执行的恶意命令时,会发生二次SQL注入。在某些情况下,应用程序可能会正确编码SQL语句并将其存储为有效的SQL。然后,该应用程序的另一部分没有控制,以防止SQL注入可能会执行存储的SQL语句。这种攻击需要更多的关于如何使用提交的值的知识。自动化Web应用程序安全扫描程序不会轻易检测到这种类型的SQL注入,并且可能需要手动指示在哪里检查它正在尝试的证据。

缓解[ 编辑]

SQL注入是众所周知的攻击,可以通过简单的措施轻松防止。在2015 年Talktalk发生明显的SQL注入攻击后,英国广播公司(BBC)报道说,安全专家惊呆了,这样一家大公司会受到影响。[18]

参数化语句[ 编辑]

主要文章:编写声明

对于大多数开发平台,可以使用参数化的参数化语句(有时称为占位符或绑定变量),而不是在语句中嵌入用户输入。占位符只能存储给定类型的值,而不是任意的SQL片段。因此,SQL注入将被简单地视为一个奇怪的(可能是无效的)参数值。

在很多情况下,SQL语句是固定的,每个参数是一个标量,而不是一个。用户输入被分配(绑定)到一个参数。[19]

在编码层面执行[ 编辑]

使用对象关系映射库避免了编写SQL代码的需要。实际上,ORM库将从面向对象的代码生成参数化的SQL语句。

转义[ 编辑]

一个简单的,虽然容易出错的防止注入的方法是转义SQL中具有特殊含义的字符。SQL DBMS手册解释了哪些字符具有特殊含义,可以创建需要翻译的字符的全面黑名单。例如,参数中每个出现的单引号(')都必须被两个单引号('')替换,形成一个有效的SQL字符串文字。例如,在PHP中,通常mysqli_real_escape_string();在发送SQL查询之前使用函数转义参数:

$ mysqli  =  new  mysqli ('hostname' , 'db_username' , 'db_password' , 'db_name' );
$ query = sprintf (“SELECT * FROM`Users` WHERE UserName ='%s'AND Password ='%s'” ,
$ mysqli - > real_escape_string ($ username ),
$ mysqli - > real_escape_string ($ password ));
$ mysqli - > query ($ query );

此功能前添加反斜杠以下字符:\x00\n\r\'"\x1a。这个函数通常用于在向MySQL发送查询之前使数据安全。[20]
有在PHP许多数据库类型,如pg_escape_string()用于其它功能的PostgreSQL。该函数addslashes(string $str)用于转义字符,特别用于在PHP中查询没有逃逸函数的数据库。它返回一个反斜杠的字符串需要在数据库查询被引用,等等。这些字符是单引号('),双引号(“),反斜线(\)和NUL(空字节)字符之前。[21]
常规地将转义字符串传递给SQL是很容易出错的,因为很容易忘记转义给定的字符串。创建透明图层来保护输入可以减少这种容易出错的情况,如果不能完全消除的话。[22]

模式检查[ 编辑]

整型,浮点型或布尔型,如果字符串参数的值是给定类型的有效表示形式,则可以检查它们。如果它们符合这种模式,则必须检查必须遵循一些严格模式(日期,UUID,仅字母数字等)的字符串。

数据库权限[ 编辑]

将Web应用程序使用的数据库登录权限限制为仅需要的权限可能有助于降低任何利用Web应用程序中的任何错误的SQL注入攻击的有效性。

例如,在Microsoft SQL Server上,可能会限制数据库登录在某些系统表上进行选择,这将限制尝试将JavaScript插入到数据库的所有文本列中的漏洞利用。

拒绝在sys上选择。系统对象到webdatabaselogon ; 拒绝在sys上选择。对象到webdatabaselogon ; 拒绝在sys上选择。表到webdatabaselogon ; 拒绝在sys上选择。对webdatabaselogon的看法; 拒绝在sys上选择。打包到webdatabaselogon ;

(其他)SQL注入(转)的更多相关文章

  1. 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范

    昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...

  2. Web安全相关(五):SQL注入(SQL Injection)

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

  3. 从c#角度看万能密码SQL注入漏洞

    以前学习渗透时,虽然也玩过万能密码SQL注入漏洞登陆网站后台,但仅仅会用,并不理解其原理. 今天学习c#数据库这一块,正好学到了这方面的知识,才明白原来是怎么回事. 众所周知的万能密码SQL注入漏洞, ...

  4. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  5. 揭开SQL注入的神秘面纱PPT分享

        SQL注入是一个老生常谈但又经常会出现的问题.该课程是我在公司内部培训的课程,现在分享出来,希望对大家有帮助.     点击这里下载.

  6. 深入理解SQL注入绕过WAF和过滤机制

    知己知彼,百战不殆 --孙子兵法 [目录] 0x0 前言 0x1 WAF的常见特征 0x2 绕过WAF的方法 0x3 SQLi Filter的实现及Evasion 0x4 延伸及测试向量示例 0x5 ...

  7. jdbc java数据库连接 8)防止sql注入

    回顾下之前jdbc的开发步骤: 1:建项目,引入数据库驱动包 2:加载驱动 Class.forName(..); 3:获取连接对象 4:创建执行sql语句的stmt对象;  写sql 5:执行sql ...

  8. Entity Framework关于SQL注入安全问题

    1.EF生成的sql语句,用 parameter 进行传值,所以不会有sql注入问题 2.EF下有涉及外部输入参数传值的,禁止使用EF直接执行sql命令方式,使用实体 SQL   参考: https: ...

  9. 关于SQL注入和如何防止

    之前在笔试的时候没有很好的答出这个问题,因此我要总结一下问题,以免日后继续在这个地方跌倒,以下是自己的理解,如有错误请指出 一.什么是SQL注入 SQL注入就是服务器在根据业务去处理数据库的时候,客户 ...

  10. Java防止SQL注入2(通过filter过滤器功能进行拦截)

    首先说明一点,这个过滤器拦截其实是不靠谱的,比如说我的一篇文章是介绍sql注入的,或者评论的内容是有关sql的,那会过滤掉:且如果每个页面都经过这个过滤器,那么效率也是非常低的. 如果是要SQL注入拦 ...

随机推荐

  1. Linux下安装mysql5.7

    Linux下安装mysql5.7   首先准备好mysql5.7.17的安装包,安装包放在  /data/software 目录下 进入到 /usr/local 目录下,解压mysql安装包 命令: ...

  2. Ubuntu 16.04 python和OpenCV安装

    Ubuntu 16.04 python和OpenCV安装:最进在做深度学习和计算机视觉的有关内容,因此要在python中用到opencv.我的电脑装的是Ubuntu 16.04,python 2.7和 ...

  3. oracle中常见的对表、表空间和视图的操作

    创建表:create table t1(key1 type default 0,key2 type not null) 删除表:drop table t1; 删除表数据:truncate table ...

  4. Spring Cloud Eureka 服务注册列表显示 IP 配置问题

    服务提供者向 Eureka 注册中心注册,默认以 hostname 的形式显示,Eureka 服务页面显示的服务是机器名:端口,并不是IP+端口的形式 ,可以通过修改服务提供者配置自己的 IP 地址, ...

  5. go 通过http发送图片file内容

    package main import ( "encoding/json" "fmt" "io/ioutil" "net/http ...

  6. Android invalidate()方法 requestLayout()方法分析

    强调一点的就是,在onMeasure(),onLayout(),onDraw()这三个流程中,Google已经帮我们把draw()过程框架已经写好了,自定义的ViewGroup只需要实现 measur ...

  7. Android使用AIDL跨进程通信

    一.基本类型 1.AIDL是什么 AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definiti ...

  8. Docker容器的创建、启动、和停止

    1.容器是独立运行的一个或一组应用,及他们的运行环境.容器是Docker中的一个重要的概念. 2.docker容器的启动有三种方式a.交互方式,基于镜像新建容器并启动例如我们可以启动一个容器,打印出当 ...

  9. PostgreSQL查询优化逻辑优化之其他

    上一节我们介绍了PostgreSQL的子查询优化,子查询优化把一部分可以优化的子查询上拉到主查询成为join. preprocess_expression 将表达式(目标列,where,join,ha ...

  10. PostgreSQL事务实现

    事务简介 事务管理器:有限状态机 日志管理器 CLOG:事务的执行结果 XLOG:undo/redo日志 锁管理器:实现并发控制,读阶段采用MVCC,写阶段采用锁控制实现不同的隔离级别 Postgre ...