正确的防御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. GNU C 与 ANSI C(上)

    Linux 上可用的 C 编译器是 GNU C 编译器,它建立在自由软件基金会的编程许可证的基础上,因此可以自由发布.GNU C 是对标准 C 进行的一系列扩展,以增强标准 C 的功能. 1. 零长度 ...

  2. iOS-CoreData详解与使用

    上面已经说完了SQLite和FMDB以及两者的区别,本篇将讲述iOS中另一个存储方式,CoreData的使用.通读下来大约10分钟,后续还会根据项目中问题,不断更新. 一.预备知识 在了解CoreDa ...

  3. Response.Redirect()和Response.RedirectPermanent()区别

    备注:这里我用到了Response.RedirectPermanent()用于做301跳转, 如:我希望访问网站的url访问地址为:http://m.shop/abc.html ,用户输入的访问地址: ...

  4. java面试教程视频

    java.从入门到精通.第28讲-面试题评讲:http://www.iqiyi.com/w_19rsdc9mu9.html java面试题 1.面试的整体流程:http://www.iqiyi.com ...

  5. struts2_struts类型转换

    一.在Servlet中,表单提交的非字符串类型需要手动转换 1.在struts中,表单提供的常见数据类型struts框架自动转换,无需手动转换 2.在某些情况下,某些自定义类型struts不能完成自动 ...

  6. Java学习笔记之——继承

    父类(基类):动物 子类:猫.狗.狼.老虎 如果子类继承于父类,则会自动拥有父类的所有非私有属性和方法,不会继承构造方法 父类和子类要满足一种关系:子类是父类的一种 Java中只支持单继承:一个子类只 ...

  7. HDU3038(KB5-D加权并查集)

    How Many Answers Are Wrong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  8. 信息检索中的TF/IDF概念与算法的解释

    https://blog.csdn.net/class_brick/article/details/79135909 概念 TF-IDF(term frequency–inverse document ...

  9. 教你分分钟搞定Docker私有仓库Registry

    一.什么是Docker私有仓库Registry 官方的Docker hub是一个用于管理公共镜像的好地方,我们可以在上面找到我们想要的镜像,也可以把我们自己的镜像推送上去.但是,有时候我们的服务器无法 ...

  10. 开发Spring过程中几个常见异常(一)

    异常一:java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory 原因:未导入有关日志管理的jar包或者未添加到路径. ...