正确的防御SQL注入

  sql注入的防御不是简单只做一些用户输入的escape处理,这样是不够的,只是提高了攻击者的门槛而已,还是不够安全。

例如 mysql_real_escape_string()函数会对输入的参数进行转义。

$sql="SELECT id,name,mail,cv,blog,twitter FROM register WHERE id= ".mysql_real_escape_string($_GET['id']);

当攻击者构造的注入代码如下时:

http://vuln.example.com/user.php?id=2,and,1=1,union,select,1,
concat(user,0x3a,password),3,4,5,6,from,mysql.user,where,
user=substring_index(current_user(),char(64),1)

 将会绕过这个函数注入成功,其原因在于这个函数仅仅会转义: '   "   \r   \n   NULL   Control-Z

这种基于黑名单的方法,或多或少地存在些问题,是不可能排除所有恶意符号或者说能利用的符号。

  围绕着SQL注入攻击产生的两个关键条件:1.用户控住的输入参数  2.拼接过程中的数据当做代码执行。

有下面几个防御措施:

一.使用预编译语句

  一般来说,防御SQL注入的最好效果就是使用预编译语句,绑定变量。例如在Java中使用预编译的SQL语句:

String userName=request.getParameter("userName");
String query="SELECT account_balance FROM user_data WHERE
user_name=?";
PreparedStatement pstmt=connection.prepareStatament(query);
pstmt.setString(1,userName);
ResultSet results=pstmt.executeQuery();

使用这种预编译的SQL语句,SQL语句的语义不会发生改变,变量用?表示,攻击者无法改变SQL的结构。

在PHP中绑定变量的示例:

$query="INSERT INTO myCity(Name,CountCode,District)VALUES(?,?,?)";
$stmt=$mysqli->prepare($query);
$stmt->bind_param("sss",$var1,$var2,$var3);
$var1="StuName";
$var2="DEU";
$var3="Bid";
$stmt->execute();

在不同的语言中,都有着预编译语句的方法:

Java EE------ PreparedStatement()

.NET------SqlCommand() or OleDbCommand()

PHP------bind_Param()

Hibernate------createQuery()

SQLite------sqlite3_prepare()

二.使用存储函数 

使用安全的存储过程对抗SQL注入。使用存储过程与预编译语句的区别在于,存储过程要先将SQL语句定义在数据库中,所以存储过程也可能存在注入问题,得尽量避免在存储过程中使用动态的SQL语句。如果业务要求,实在无法避免,则可以考虑加上严格的输入过滤或者是编码函数来处理用户的输入数据。

Java中存储过程的示例,其中sp_getAccount是预先在数据中定义好的存储过程。

String username=request.getParameter("userName");
try{
CallableStatement cs=
connection.prepareCall(" {call sp_getAccount(?)} ");
cs.setString(1,username);
ResultSet results=cs.executeQuery();
}catch(SQLException se){
//....some error info and error handing
}

三.检查数据类型

检出数据类型,在很大程度上能够对抗SQL注入。

比如下面这段代码,就限制了输入数据只能为integer。

<?php

settype($offset,'integer');
$query="SELECT id ,name FROM produces ORDER BY name LIMIT
20 OFFSET ;"; $query=sprintf("SELECT id ,name,FROM produces ORDER BY name LIMIT 20 OFFSET %d;");
?>

其他数据格式或者类型检查也是有益的,但是提交字符串,则需要依赖其他的方法防御SQL注入,而不能使用'%s"代换"%d"。

四.使用安全函数

安全函数,数据库厂商都往往对此都做出了“指导”。可以参考OWASP ESAPI中的实现。这个函数由安全专家编写的,更值得信赖。

ESAPI.encoder().encoderForSQL(new OracleCodec(),queryparam);

使用示例:

Codec ORACLE_CODEC=new OracleCode();
String query="SELECT user_id FROM user_data WHERE user_name=' "+
ESAPI.encoder().encoderForSQL( ORACLE_CODEC,req.getParameter("userID"))+" ' and
user_password=' "+
ESAPI.encoder().encoderForSQL( ORACLE_CODEC,req.getParameter("pwd"))+" ' ";

注入攻击(SQL注入防御)的更多相关文章

  1. 注入攻击-SQL注入和代码注入

    注入攻击 OWASP将注入攻击和跨站脚本攻击(XSS)列入网络应用程序十大常见安全风险.实际上,它们会一起出现,因为 XSS 攻击依赖于注入攻击的成功.虽然这是最明显的组合关系,但是注入攻击带来的不仅 ...

  2. 注入攻击(SQL注入)

    注入攻击是web安全领域中一种最为常见的攻击方式.注入攻击的本质,就是把用户输入的数据当做代码执行.这里有两个关键条件,第一是用户能够控制输入,第二个就是原本程序要执行的代码,将用户输入的数据进行了拼 ...

  3. XSS攻击&SQL注入攻击&CSRF攻击?

    - XSS(Cross Site Script,跨站脚本攻击)是向网页中注入恶意脚本在用户浏览网页时在用户浏览器中执行恶意脚本的攻击方式.跨站脚本攻击分有两种形式:反射型攻击(诱使用户点击一个嵌入恶意 ...

  4. XPath注入跟SQL注入差不多,只不过这里的数据库走的xml格式

    SQL注入这块不想细聊了,相信很多朋友都听到耳朵长茧,不外乎是提交含有SQL操作语句的信息给后端,后端如果没有做好过滤就执行该语句,攻击者自然可以随意操纵该站点的数据库. 比如有一个图书馆站点book ...

  5. False注入,以及SQL注入技巧总结

    title: False注入,以及SQL注入技巧总结 date: 2017-04-25 00:23:31 tags: ['SQL注入'] --- 利用False我们可以绕过一些特定的WAF以及一些未来 ...

  6. 防止sql注入式攻击 SQL注入学习——三层架构

    解决方案是:1.首先在UI录入时,要控制数据的类型和长度.防止SQL注入式攻击,系统提供检测注入式攻击的函数,一旦检测出注入式攻击,该数据即不能提交:2.业务逻辑层控制,通过在方法内部将SQL关键字用 ...

  7. xss 攻击 sql 注入

    XSS测试 "/><script>alert(document.cookie)</script><!-- <script>alert(docu ...

  8. 最新SQL手工注入语句&SQL注入大全

    看看下面的1.判断是否有注入;and 1=1;and 1=2 2.初步判断是否是mssql;and user>0 3.判断数据库系统;and (select count(*) from syso ...

  9. SQL注入 (1) SQL注入类型介绍

    SQL注入 SQL注入介绍与分类 1. 什么是sql注入 通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. 2. sql注入类型 按照注入 ...

随机推荐

  1. man sm-notify(sm-notify命令中文手册)

    本人译作集合:http://www.cnblogs.com/f-ck-need-u/p/7048359.html sm-notify命令是用来发送重启通知信息给NFS对端的,在锁状态恢复过程中起着至关 ...

  2. python模块之xml

    xml模块 xml结构 xml是种实现不同语言或程序之间进行数据交换的协议,跟json差不多,但没json使用简单.但是因为历史遗留问题,至今很多行业依然使用xml这种数据格式. xml的格式如下,是 ...

  3. 自定义input文件上传样式

    前言 文件上传是我们经常会用到的功能,但是原生的input样式太丑了,能不能自定义一个input文件上传样式呢?我这里写了两种方法,form表单提交跟ajax异步提交都没有问题,自动上传或者点击上传按 ...

  4. SpringBoot学习(五)-->SpringBoot的核心

    SpringBoot的核心 1.入口类和@SpringBootApplication Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的J ...

  5. Java并发(一)—— 使用多线程

    Java的线程机制是抢占式的,所谓的抢占式指的是每一个线程都会被分配一个指定大小的时间片,一旦这个时间片用完,就会通过上下文切换到另一个线程上去. 并发是主要是为了提高单处理器的性能.创建一个线程会有 ...

  6. 第一册:lesson twenty-one.

    原文:Which book? A:Give me a book please,B. B:Which book? This one? A:No,not that one. The red one. B: ...

  7. input type=file 上传文件样式美化(转载)

    input type=file 上传文件样式美化 来源:https://www.jianshu.com/p/6390595e5a36 在做input文本上传时,由于html原生的上传按钮比较丑,需要对 ...

  8. C#判断输入的是否为数字(int.TryParse)

    了解 TryParse: TryParse静态方法用来将字符串转换成对应类型的数值. 所以int.TryParse()是将字符串转换为int类型的,如果成功返回true,失败返回false. priv ...

  9. 程序员晋级CTO之路的8大准则

    推荐阅读: 大数据智慧平台落地方案 Nginx + 阿里云SSL + tomcat 实现https访问代理 永远别忘了TD 再确认测试代码前,先找别人帮你检查下是否无误.在别人做之前尽量检查出bug并 ...

  10. HTML 介绍及标签

    HTML htyper text markup language 即超文本标记语言 超文本: 就是指页面内可以包含图片.链接,甚至音乐.程序等非文字元素. 标记语言: 标记(标签)构成的语言. 标签 ...