开发过程中需要对用户的输入进行转义,不论是安全地显示用户在表单提交中输入的数据,还是在处理 sql 语句时,进行安全地转义可以有效避免跨站脚本攻击(XSS)和 SQL 注入。
1. 使用 htmlentities() 和 htmlspecialchars()
在处理用户提交的表单数据时,先将用户的输入进行转义,再显示在页面上。
可以使用 htmlentities() 和 htmlspecialchars() 函数将 HTML 实体转换成字符串。最基本的是 htmlspecialchars(),可以转义 4 个字符: < > " 和 &(可以根据可选的参数决定转义的字符)。对于更复杂的编码,需要使用 htmlentities(),可以对任何 HTML 实体进行转换。
例:
<?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));
时间: 2024-12-22 19:15:33