`

PHP中SQL注入与跨站攻击的防范

    博客分类:
  • php
阅读更多
  SQL injection即SQL注入是我们每个WEB程序员都需要面对的问题,一个WEB应用假如没有起码的安全性,那么其它的一切就可以免谈了。注入问题在ASP上可谓是闹得沸沸扬扬,当然还有不少PHP程序“遇难”。至于SQL injection的详情,网上的文章很多,在此就不作赘述。追其罪恶之源,就是我们误以为用户提交的数据是可靠的。

    无论你是否有足够的PHP安全开发经验,本文的目的就是用来帮助你构建更为安全的在线应用程序。针对不同的情况,我们可以使用下面的一种或几种方法来对SQL注入的风险进行预防。

    1、在书写SQL语句时不要省略单引号,即使是整型字段也应该加上单引号。
    首先,从技术上讲,引号对于数字值来说是不需要使用的。但是,假如你不使用引号把例如书籍数量这样的一个值括起来,并且假如你的用户把一个空值输入到你的表单中,那么,你将会看到一个类似下面的查询:
SELECT * FROM books WHERE num =
    当然,这个查询从语法上讲是无效的;但是,下面的语法却是有效的:
SELECT * FROM books WHERE num = ''
    第二个查询虽然也不会返回任何结果,但是至少它不会返回一个错误消息。
    其次,单引号可以增加注入者的难度,第二句由于把变量放在一对单引号中,这样使得我们所提交的变量都变成了字符串,即使包含了正确的SQL语句,也不会正常执行,而第一句不同,由于没有把变量放进单引号中,那我们所提交的一切,只要包含空格,那空格后的变量都会作为SQL语句执行,因此,我们要养成给SQL语句中变量加引号的习惯。

    2、检查用户提交的值的类型,对接收到的整型参数使用intval()强制转换成整形。
    我们知道SQL注入的主要来源往往出在一个意料之外的表单提交或URL参数中,所以当你接受一个由用户提交的参数时,你应该有相当的权利来确定你想取得什么样的输入内容。在以前的学习中我们已经讨论过很多这样或那样的校验问题。因此我们只要简单的总结当时我们讨论的要点即可比较轻易的检查用户提交数据的有效性。假如你期望得到的是一个数值,那么你可以使用下面这些技术之一来确保你得到的参数的安全性。
使用is_int()函数(或is_integer()或is_long())。
使用gettype()函数。
使用intval()函数。
使用settype()函数。
    我们通常把传送过来的整型参数使用intval()函数强制转换成整形,因为假如不这样做,接收到的查询子句很可能会附带着其它一些我们并不愿看到的语句,比如原本应该是“nid=17”可能会成为“nid=17 or 1=1”,这会使我们预计的SQL语句变成这样:
SELECT * FROM news WHERE nid=17 or 1=1
这对于一个新闻表中的信息可能不会造成什么大的危害,但假如是在显示某个用户的信息时呢?
    此外,为了检查用户输入内容的长度,你可以使用strlen()函数。为了检查一个期望的时间或日期是否有效,你可以使用strtotime()函数。它似乎一定能够确保一位用户的提交参数中没有包含分号字符(除非标点符号可以被合法地包括在内)。你可以借助于strpos()函数轻易地实现这一点,如下所示:
if( strpos( $variety, ';' ) ) exit ( "$variety is an invalid value for variety!" );
正如我们在前面所提到的,只要你仔细分析你的用户输入期望,那么,你应该能够很轻易地检查出其中存在的许多问题。

    3、使用mysql_real_escape_string()函数从查询字符串中过滤掉危险字符
    尽管有很多文章已经讨论过如何过滤掉危险字符的问题,但是在本文中还是让我们再次简单的强调并归纳一下这个问题:
    不要使用magic_quotes_gpc指令或它的搭挡addslashes()函数,此函数在程序开发中应该是被限制使用的,在PHP的下一个版本PHP6中已经取消了对此函数的支持,并且此函数还要求使用额外的步骤stripslashes()函数。相比之下,mysql_real_escape_string()函数更为适合,受此函数影响的字符包括:\x00,\n,\r,\,',",\x1a。这二个函数的功能类似,但addslashes()函数无法转换以十六进制形式提交的字符,另外需要注重的是,mysqli_real_escape_string()函数需要先建立数据库连接,因为需要考虑到连接的当前字符集,通常防止数据库被攻击的使用方法如下:
<?php
function check_input($value)
{
// 去除斜杠
if (get_magic_quotes_gpc())
  {
  $value = stripslashes($value);
  }
// 假如不是数字则加引号
if (!is_numeric($value))
  {
  $value = "'" . mysqli_real_escape_string($value) . "'";
  }
return $value;
}
?>

    4、对用户输入的字符进行HTML编码以防止跨站攻击
    对于数据库防止SQL注入的问题,通过前面三点所述综合的运用我们似乎全部解决,但假如用户提交的内容中有一些不良的HTML标签则可能会导致页面变形,严重的还可能会出现跨站攻击之类的安全问题,所以对带有HTML的内容增加过滤检查是很有必要的。
    例如一段接收用户的输入并显示的功能代码,一但恶意用户输入:<script type='text/javascript'>location.href='http://xxx.com';</script>这样的一条数据,网页在显示该条数据时,用户的浏览器将会跳转到恶意代码指定的地址,这就是最简单的跨站攻击,我们试想一下,假如跳转的地址是一个伪造原网站来骗取用户密码或银行信息的页面,那么会是什么样的后果?
    对于这类攻击行为,就需要我们在接收用户提交的数据时在服务器端进行过滤,我们可以编写一个过滤函数用来查询提交数据中有害字符并将之替换掉,还有一种较简便的方式就把用户所提交的内容中“<”,“>”,“&”等符号转换成正确的HTML编码,而函数htmlspecialchars()正是干这个活的。
htmlspecialchars()
功能:将“'"&<>”五个字符转换成HTML字符串。
语法:string htmlspecialchars(string,quotestyle,character-set);
参数:ENT_NOQUOTES,不对任何引号进行格式化;ENT_QUOTES,对单引号及双引号进行格式化;默认为ENT_COMPAT,仅编码双引号。
返回值:字符串

因此,用户提交的数据经过格式化后为:
&lt;script type=&#039;text/javascript&#039;&gt;location.href=&#039;http://xxx.com&#039;;&lt;/script&gt;
这样代码就失去了原有的攻击功能,可以基本预防脚本攻击的潜在危险,假如不明白这之间的区别,可以测试下面这段代码:
<?php
$str="<a href='http://www.php3c.com'>PHP3C技术分享社区</a>";
echo $str;
echo "<br>";
echo htmlspecialchars($str);
?>
    另外,转换非凡字符为HTML字符串还可以使用函数htmlentities(),使用方法相同,它与htmlspecialchars在格式化带有英文字符的html代码的时候没有什么区别,但是htmlentities对中文字符也不放过,所以同样的调用方法得出来的结果是由于没有指定字符集而默认由 ISO-8859-1 代替,中文字符部分变为一堆乱码,因此我们在使用的时候,需要指定参数character-set为我们页面使用的字符集,例如'UTF-8'或'GB2312'。

    SQL注入攻击是针对服务器端的数据库实行的,而跨站脚本攻击是把恶意javascript代码在用户的客户端运行,但他们的相同之处在于攻击者必须通过互联网的输入区域插入恶意的数据,因此我们只要做好用户提交数据的过滤以及合法性验证就能从源头上制止这二类攻击,但这种过滤及验证被很多程序员所忽视的,希望本文能能引起大家的重视。

分享到:
评论

相关推荐

    SQL注入全面讲解技术文档

    8.PHP与SQL注入攻击 29 9.SQL注入攻击零距离 30 10.SQL注入技术和跨站脚本攻击的检测 34 11.菜鸟入门级:SQL注入攻击 39 12. SQL注入渗透某网络安全公司的网站全过程 42 13.利用SQL注入2分钟入侵网站全程实录 45

    PHP中SQL注入式攻击的实现与防范.pdf

    PHP中SQL注入式攻击的实现与防范。

    php中mysql数据库的sql注入与全面防范

    SQL Injection问题在ASP上闹得沸沸扬扬,php也不免于难。为此我们也会采取一些防范。通过具体实例来描述在php中的mysql的sql注入问题以及怎样去防范。

    PHPSQL注入漏洞学习

    详细讲解了PHPsql注入漏洞的类型,及其防范措施,对开发网站,深入了解sql的人会有一定的帮助。

    PHP代码网站防范SQL注入漏洞攻击的建议.docx

    PHP代码网站防范SQL注入漏洞攻击的建议.docx

    防范SQL注入的应用分析

    Web服务器脚本攻击事件的增多反映出各种Web服务器漏洞的非...文章简要介绍了SQL注入攻击的概念和原理,以及SQL注入攻击的特点和实现过程,并在此基础上叙述了如何检测SQL注入攻击,总结了一般的SQL注入攻击的防范方法。

    PHP与SQL注入攻击[一]

    SQL注入攻击通常通过给站点数据库提交不良的数据或查询语句来实现,很可能使数据库中的纪录遭到暴露,更改或被删除。下面来谈谈SQL注入攻击是如何实现的,又如何防范。 看这个例子: // supposed input $name = ...

    计算机后端-PHP视频教程. php之blog实战49-sql注入与防范.wmv

    计算机后端-PHP视频教程. php之blog实战49-sql注入与防范.wmv

    PHP代码网站如何防范SQL注入漏洞攻击建议分享

    今天就通过PHP和MySQL数据库为例,分享一下我所了解的SQL注入攻击和一些简单的防范措施和一些如何避免SQL注入攻击的建议。 什么是SQL注入(SQL Injection)? 简单来说,SQL注入是使用代码漏洞来获取网站或应用程序...

    初探PHP的SQL注入攻击的技术实现以及预防措施

    有部份人认为SQL注入攻击是只针对MicrosoftSQLServer而来,但只要是支持批处理SQL指令的数据库服务器,都有可能受到此种手法的攻击。在应用程序中若有下列状况,则可能应用程序正暴露在SQLInjection的高风险情况下:...

    基于PHP MySQL的用户登录系统SQL注入实例及防范.pdf

    基于PHP MySQL的用户登录系统SQL注入实例及防范.pdf

    PHP与SQL注入攻击防范小技巧

    SQL注入攻击是黑客攻击网站最常用的手段。如果你的站点没有使用严格的用户输入检验,那么常容易...SQL注入攻击通常通过给站点数据库提交不良的数据或查询语句来实现,很可能使数据库中的纪录遭到暴露,更改或被删除。

    php防止SQL注入详解及防范

    SQL 注入是PHP应用中最常见的漏洞之一。事实上令人惊奇的是,开发者要同时犯两个错误才会引发一个SQL注入漏洞

    PHP中的代码安全和SQL Injection防范1

    SQL 注射应该是目前程序危害最大的了,包括最早从asp到php,基本上都是国内这两年流行的技术,基本原理就是通过对提交变量的不过滤形成注入点然后使恶意用户能够提交一些sql查询语句,导致重要数据被窃取、数据丢失...

    浅谈开启magic_quote_gpc后的sql注入攻击与防范

    配置文件中的相关选项,就可以将大部分想利用SQL注入漏洞的骇客拒绝于门外。 开启magic_quote_gpc=on之后,能实现addslshes()和stripslashes()这两个函数的功能。在PHP4.0及以上的版本中,该选项默认情况下是开启的...

    PHP数据库陷阱-数据库安全知识集合

    主要讲解PHP数据库陷阱等安全方面的知识,主要讲解的内容有sq1注入原理解释、搭建php开发环境+做出框架图、创建测试...SQL注入的方式形式很多,有的时候防不胜防,韩老师仪具体的案例介绍了如何防范PHP数据库注入攻击。

Global site tag (gtag.js) - Google Analytics