PHP防止SQL注入和XSS攻击

244次阅读
没有评论

原文链接:http://blog.csdn.net/u011781769/article/details/48470759

PHP 所有打印的语句如 echo,print 等,在打印前都要使用 htmlentities() 进行过滤,

这样可以防止 Xss,注意中文要写出 htmlentities($name, ENT_NOQUOTES, GB2312) 

 

mysql_real_escape_string() 

所以 SQL 语句如果有类似这样的写法:

“select * from cdr where src =”.$userId;

都要改成

$userId=mysql_real_escape_string($userId)

 

PHP 防范 SQL 注入

PHP 防范 SQL 注入是一个非常重要的安全手段。一个优秀的 PHP 程序员除了要能顺利的编写代码,还需要具备使程序处于安全环境下的能力。

说到网站安全就不得不提到 SQL 注入(SQL Injection),如果你用过 ASP,对 SQL 注入一定有比较深的理解,PHP 的安全性相对较高,这是因为 MYSQL4 以下的版本不支持子语句,而且当 php.ini 里的 magic_quotes_gpc 为 On 时。

提交的变量中所有的‘(单引号),”(双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符,给 SQL 注入带来不少的麻烦。

请看清楚:

“麻烦”而已,这并不意味着 PHP 防范 SQL 注入,书中就讲到了利用改变注入语句的编码来绕过转义的方法,比如将 SQL 语句转成 ASCII 编码(类似:char(100,58,92,108,111,99,97,108,104,111,115,116…) 这样的格式),或者转成 16 进制编码,甚至还有其他形式的编码,这样以来,转义过滤便被绕过去了,那么怎样防范呢?

 

a. 打开 magic_quotes_gpc 或使用 addslashes() 函数

在新版本的 PHP 中,就算 magic_quotes_gpc 打开了,再使用 addslashes() 函数,也不会有冲突,但是为了更好的实现版本兼容,建议在使用转移函数前先检测 magic_quotes_gpc 状态,或者直接关掉,代码如下:

PHP 防范 SQL 注入的代码

// 去除转义字符
function stripslashes_array($array) {
if (is_array($array)) {
foreach ($array as $k => $v) {
$array[$k] = stripslashes_array($v);
}
} else if (is_string($array)) {
$array = stripslashes($array);
}
return $array;
}
@set_magic_quotes_runtime(0);
// 判断 magic_quotes_gpc 状态
if (@get_magic_quotes_gpc()) {
$_GET = stripslashes_array($_GET);
$_POST = stripslashes_array($_POST);
$_COOKIE = stripslashes_array($_COOKIE);
}

 

PHP 防范 SQL 注入的代码

去除 magic_quotes_gpc 的转义之后再使用 addslashes 函数,代码如下:

$keywords = addslashes($keywords);
$keywords = str_replace(“_”,”\_”,$keywords);// 转义掉”_”
$keywords = str_replace(“%”,”\%”,$keywords);// 转义掉”%”

后两个 str_replace 替换转义目的是防止黑客转换 SQL 编码进行攻击。

 

b. 强制字符格式(类型)

在很多时候我们要用到类似 xxx.php?id=xxx 这样的 URL,一般来说 $id 都是整型变量,为了防范攻击者把 $id 篡改成攻击语句,我们要尽量强制变量,代码如下:

PHP 防范 SQL 注入的代码

$id=intval($_GET[‘id’]);

当然,还有其他的变量类型,如果有必要的话尽量强制一下格式。

 

c. SQL 语句中包含变量加引号

这一点儿很简单,但也容易养成习惯,先来看看这两条 SQL 语句:

SELECT * FROM article WHERE articleid=’$id’
SELECT * FROM article WHERE articleid=$id

两种写法在各种程序中都很普遍,但安全性是不同的,第一句由于把变量 $id 放在一对单引号中,这样使得我们所提交的变量都变成了字符串,即使包含了正确的 SQL 语句,也不会正常执行,而第二句不同,由于没有把变量放进单引号中,那我们所提交的一切,只要包含空格,那空格后的变量都会作为 SQL 语句执行,因此,我们要养成给 SQL 语句中变量加引号的习惯。

 

d. URL 伪静态化

URL 伪静态化也就是 URL 重写技术,像 Discuz!一样,将所有的 URL 都 rewrite 成类似 xxx-xxx-x.html 格式,既有利于 SEO,又达到了一定的安全性,也不失为一个好办法。但要想实现 PHP 防范 SQL 注入,前提是你得有一定的“正则”基础。

正文完
有偿技术支持加微信
post-qrcode
 0
评论(没有评论)
验证码