关于转义

开发过程当中须要对用户的输入进行转义,不管是安全地显示用户在表单提交中输入的数据,仍是在处理 sql 语句时,进行安全地转义能够有效避免跨站脚本攻击(XSS)和 SQL 注入。php

 

1. 使用 htmlentities() 和 htmlspecialchars()html

在处理用户提交的表单数据时,先将用户的输入进行转义,再显示在页面上。mysql

能够使用 htmlentities() 和 htmlspecialchars() 函数将特殊字符转换成 HTML 实体(例如把 < 转换成 &lt;)。最基本的是 htmlspecialchars(),能够转义 4 个字符: < > " 和 &(能够根据可选的参数决定转义的字符)。对于更复杂的编码,须要使用 htmlentities(),能够对任何 HTML 实体进行转换。sql

 

例:chrome

<?php

$html = "<script>alert('<a href=\"http://baidu.com?user=dee&browser=chrome\">baidu.com</a>');</script>";

echo $html,PHP_EOL; //会弹出alert提示框
//浏览器右键查看源代码
//<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script>

echo htmlentities($html),PHP_EOL; 
//浏览器右键查看源代码
//<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script>

echo htmlspecialchars($html),PHP_EOL;								//转义双引号 < > &
//浏览器右键查看源代码
//<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script>

echo htmlspecialchars($html, ENT_QUOTES),PHP_EOL;		//转义双引号和单引号 < > &
//浏览器右键查看源代码
//<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script>

echo htmlspecialchars($html, ENT_NOQUOTES),PHP_EOL;	//非单引号和双引号
//浏览器右键查看源代码
//<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script>

  

2. 防止注入攻击,建议使用 PDO 的参数绑定浏览器

使用参数绑定时,PDO 会对各个参数加引号和进行转义安全

例:服务器

<?php

$user = 'root';
$pwd = '';
try{
	$mysql = new PDO('mysql:host=127.0.0.1;port=3306;dbname=test', $user, $pwd);
} catch(Exception $e) {
	print 'Database problem:'.$e->getMessage();
	die;
}

$st = $mysql->prepare('INSERT INTO family (id,name,is_naive) VALUES (?,?,?)');
$st->execute(array('','Lee',0));

 

若是不使用参数绑定,则须要自行转义:手动加引号,而且将 SQL 的通配符 _ 和 % 也进行 \ 转义函数

<?php

$user = 'root';
$pwd = '';

try{
	$mysql = new PDO('mysql:host=127.0.0.1;port=3306;dbname=test', $user, $pwd);
} catch(Exception $e) {
	print 'Database problem:'.$e->getMessage();
	die;
}

$str = "dee's_ books%";

/*使用PDO::quote()自行转义*/
echo $str,"<br />"; 
// dee's_ books%

echo $safe = $mysql->quote($str),"<br />"; 
// 'dee\'s_ books%'

$safe = strtr($safe, array('_'=>'\_', '%'=>'\%'));
echo $safe;
// 'dee\'s\_ books\%'

$st = $mysql->query("SELECT * FROM files WHERE contents LIKE $safe");

 

注意:不管是自定义转义仍是使用 PDO::quote() 转义以前,都要判断服务器是否开启了魔法引号(magic_quotes_gpc 在 PHP 5.4.0 中被移除),若是开启了 magic_quotes_gpc,则关闭或者使用 addlashes() 处理传入的参数(尽可能关闭魔法引号):编码

/* magic_quotes_sybase 为 0 时,addlashes() 对 ' " \ 进行 \ 转义 */
/* magic_quotes_sybase 为 1 时,addlashes() 对 ' 进行 " 转义 */
if(get_magic_quotes_gpc() && ! ini_get('magic_quotes_sybase')) {
	$str = stripslashes($str);
} 

$st = $mysql->prepare('UPDATE files SET contents = ? WHERE id = 1');
$st->execute(array($str));

   

参考:PHP防SQL注入不要再用addslashes和mysql_real_escape_string了

相关文章
相关标签/搜索