热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在PHP中全面禁止SQL注进式攻击之三

另一方面,应用这个库存在一个突出的毛病:你只能受限于某些人的思想,而且代码治理方面也添加了大批的工作。为此,在决定是否应用它们之前,你需要进行仔细地考虑。假如你决定这样做,那么,你至少确保它们能够真正帮助你'清算'你的用户输进的内容

一、 建立一个安全抽象层

  我们并不建议你手工地把前面先容的技巧利用于每一个用户输进的实例中,而是强烈推荐你为此创立一个抽象层。一个简略的抽象是把你的校验计划参加到一个函数中,并且针对用户输进的每一项调用这个函数。当然,我们还可以创立一种更复杂的更高一级的抽象-把一个安全的查询封装到一个类中,从而利用于全部利用程序。在网上已经存在很多这种现成的免费的类;在本篇中,我们正要讨论其中的一些。

  进行这种抽象至少存在三个长处(而且每一个都会改良安全级别):

  1. 本地化代码。

  2. 使查询的结构更快且更为可靠-由于这可以把部分工作交由抽象代码来实现。

  3. 当基于安全特点进行构建并且适当应用时,这将会有效地防止我们前面所讨论的各种各样的注进式攻击。

  二、 改良现有的利用程序

  假如你想改良一个现有的利用程序,则应用一个简略的抽象层是最适当的。一个能够简略地'清算'你所收集的任何用户输进内容的函数可能看起来如下所示:

function safe( $string ) {
 return ''' . mysql_real_escape_string( $string ) . '''
}
  【留心】我们已经构建了相应于值请求的单引号以及mysql_real_escape_string()函数。接下来,就可以应用这个函数来结构一个$query变量,如下所示:

$variety = safe( $_POST['variety'] );
$query = ' SELECT * FROM wines WHERE variety=' . $variety;
  现在,你的用户试图进行一个注进式攻击-通过输进下列内容作为变量$variety的值:

lagrein' or 1=1;
  留心,假如不进行上面的'清算',则最后的查询将如下所示(这将导致无法预感的成果):

SELECT * FROM wines WHERE variety = 'lagrein' or 1=1;'
  然而现在,既然用户的输进已经被清算,那么查询语句就成为下面这样一种无迫害的情势:

SELECT * FROM wines WHERE variety = 'lagrein\' or 1=1\;'

  既然数据库中不存在与指定的值相应的variety域(这正是恶意用户所输进的内容-lagrein' or 1=1;),那么,这个查询将不能返回任何成果,并且注进将会失败。

  三、 保护一个新的利用程序

  假如你正在创立一个新的利用程序,那么,你可以从头开端创立一个安全抽象层。如今,PHP 5新改良的对于MySQL的支撑(这重要体现在新的mysqli扩大中)为这种安全特点供给了强有力的支撑(既有过程性的,也有面向对象特点的)。你可以从站点http://php.net/mysqli上获取有关mysqli的信息。留心,只有当你应用--with-mysqli=path/to/mysql_config选项编译PHP时,这种mysqli支撑才可用。下面是该代码的一个过程性版本,用于保护一个基于mysqli的查询:



<?php
 //检索用户的输进
 $animalName = $_POST['animalName'];
 //连接到数据库
 $cOnnect= mysqli_connect( 'localhost', 'username', 'password', 'database' );
 if ( !$connect ) exit( 'connection failed: ' . mysqli_connect_error() );
 //创立一个查询语句源
 $stmt = mysqli_prepare( $connect,'SELECT intelligence FROM animals WHERE name = ?' );
 if ( $stmt ) {
  //把调换绑定到语句上
  mysqli_stmt_bind_param( $stmt, 's', $animalName );
  //履行该语句
  mysqli_stmt_execute( $stmt );
  //检索成果...
  mysqli_stmt_bind_result( $stmt, $intelligence );
  // ...并显示它
  if ( mysqli_stmt_fetch( $stmt ) ) {
   print 'A $animalName has $intelligence intelligence.\n';
  } else {
   print 'Sorry, no records found.';
  }
  //清除语句源
  mysqli_stmt_close( $stmt );
 }
 mysqli_close( $connect );
?>
  该mysqli扩大供给了一组函数用于结构和履行查询。而且,它也非常准确地供给了前面应用我们自己的safe()函数所实现的功效。

  在上面的片段中,首先收集用户提交的输进内容并建立数据库连接。然后,应用mysqli_prepare()函数创立一个查询语句源-在此命名为$stmt以反应应用它的函数的名称。这个函数应用了两个参数:连接资源和一个字符串(每当你应用扩大插进一个值时,'?'标记被插进到其中)。在本例中,你仅有一个这样的值-动物的名字。

  留心,在一个SELECT语句中,放置'?'标记的唯一的有效地位是在值比拟部分。这正是为什么你不需要指定应用哪个变量的原因(除了在mysqli_stmt_bind_param()函数中之外)。在此,你还需要指定它的类型-在本例中,'s'代表字符串。其它可能的类型有:'I'代表整数,'d'代表双精度数(或浮点数),而'b'代表二进制字符串。

  函数mysqli_stmt_execute(),mysqli_stmt_bind_result()和mysqli_stmt_fetch()负责履行查询并检索成果。假如存在检索成果,则显示它们;假如不存在成果,则显示一条无害的消息。最后,你需要封闭$stmt资源以及数据库连接-从内存中对它们加以开释。

  假定一个正当的用户输进了字符串'lemming',那么这个例程将(假定是数据库中适当的数据)输出消息'A lemming has very low intelligence.'。假定存在一个尝试性注进-例如'lemming' or 1=1;',那么这个例程将打印(无害)消息'Sorry, no records found.'。
此外,mysqli扩大还供给了一个面向对象版本的雷同的例程。下面,我们想阐明这种版本的应用方法。

<?php
 $animalName = $_POST['animalName'];
 $mysqli = new mysqli( 'localhost', 'username', 'password', 'database');
 if ( !$mysqli ) exit( 'connection failed: ' . mysqli_connect_error() );
 $stmt = $mysqli->prepare( 'SELECT intelligence

 FROM animals WHERE name = ?' );
 if ( $stmt ) {
  $stmt->bind_param( 's', $animalName );
  $stmt->execute();
  $stmt->bind_result( $intelligence );
  if ( $stmt->fetch() ) {
   print 'A $animalName has $intelligence intelligence.\n';
  } else {
   print 'Sorry, no records found.';
  }
  $stmt->close();
 }
 $mysqli->close();
?>
  实际上,这部分代码是前面描写代码的复制-它应用了一种面向对象的语法和组织方法,而不是严格的过程式代码。


  四、 更高级的抽象

  假如你应用外部库PearDB,那么,你可以对利用程序的安全保护模块进行全面的抽象。

  另一方面,应用这个库存在一个突出的毛病:你只能受限于某些人的思想,而且代码治理方面也添加了大批的工作。为此,在决定是否应用它们之前,你需要进行仔细地考虑。假如你决定这样做,那么,你至少确保它们能够真正帮助你'清算'你的用户输进的内容。

  五、 测试你的注进式保护才能

  正如我们在前面所讨论的,确保你的脚本安全的一个重要的部分是对它们进行测试。为此,最好的措施是你自己创立SQL代码注进测试。
在此,我们供给了一个这种测试的示例。在本例中,我们测试对一个SELECT语句的注进式攻击。

<?php
//被测试的保护函数
function safe( $string ) {
 return ''' . mysql_real_escape_string( $string ) . '''
}
//连接到数据库
///////////////////////
//试图进行注进
///////////////////////
$exploit = 'lemming' AND 1=1;';
//进行清算
$safe = safe( $exploit );
$query = 'SELECT * FROM animals WHERE name = $safe';
$result = mysql_query( $query );
//测试是否保护是足够的
if ( $result && mysql_num_rows( $result ) == 1 ) {
 exitt 'Protection succeeded:\n
 exploit $exploit was neutralized.';
}
else {
 exit( 'Protection failed:\n
 exploit $exploit was able to retrieve all rows.' );
}
?>
  假如你想创立这样的一个测试集,并实验基于不同的SQL命令的各种不同的注进,那么,你将会很快地探测出你的保护策略中的任何漏洞。一旦改正这些标题,那么,你就可以很有把握-你已经建立起真正的注进式攻击保护机制。

  六、 小结

  在本系列文章一开端,我们通过一个SQL注进讨论分析了对你的脚本的特定要挟-由不适当的用户输进所致。之后,我们描写了SQL注进的工作原理并准确地分析了PHP是怎样易于被注进的。然后,我们供给了一个实际中的注进示例。之后,我们推荐一系列措施来使试图的注进攻击变为无害的-这将分辨通过确保使所有提交的值以引号封闭,通过检查用户提交值的类型,以及通过过滤掉你的用户输进的埋伏危险的字符等方法来实现的。最后,我们推荐,你最好对你的校验例程进行抽象,并针对更改一个现有利用程序供给了脚本示例。然后,我们讨论了第三方抽象计划的优毛病。


推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 探讨一个老旧 PHP MySQL 系统中,时间戳字段不定期出现异常值的问题及其可能原因。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 解决PHP与MySQL连接时出现500错误的方法
    本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ... [详细]
  • 在哈佛大学商学院举行的Cyberposium大会上,专家们深入探讨了开源软件的崛起及其对企业市场的影响。会议指出,开源软件不仅为企业提供了新的增长机会,还促进了软件质量的提升和创新。 ... [详细]
  • 本文探讨了适用于Spring Boot应用程序的Web版SQL管理工具,这些工具不仅支持H2数据库,还能够处理MySQL和Oracle等主流数据库的表结构修改。 ... [详细]
  • MySQL中枚举类型的所有可能值获取方法
    本文介绍了一种在MySQL数据库中查询枚举(ENUM)类型字段所有可能取值的方法,帮助开发者更好地理解和利用这一数据类型。 ... [详细]
author-avatar
mobiledu2502886131
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有