跨站点脚本攻击
在跨站点脚本(XSS)攻击中,往往有一个恶意用户在表单中(或通过其他用户输入方式)输入信息,这些输入将恶意的客户端标记插入过程或数据库中。例如,假设站点上有一个简单的来客登记簿程序,让访问者能够留下姓名、电子邮件地址和简短的消息。恶意用户可以利用这个机会插入简短消息之外的东西,比如对于其他用户不合适的图片或将用户重定向到另一个站点的 JavaScript,或者窃取 cookie 信息。
幸运的是,PHP 提供了 strip_tags()
函数,这个函数可以清除任何包围在 HTML 标记中的内容。strip_tags()
函数还允许提供允许标记的列表,比如 <b>
或 <i>
。
清单 16 给出一个示例,这个示例是在前一个示例的基础上构建的。
if ( $_POST [ ' submit ' ] == " go " ){
// strip_tags
$name = strip_tags ( $_POST [ ' name ' ]);
$name = substr ( $name , 0 , 40 );
// clean out any potential hexadecimal characters
$name = cleanHex( $name );
// continue processing....
}
function cleanHex( $input ){
$clean = preg_replace
( " ![][xX]([A-Fa-f0-9]{1,3})! " , "" , $input );
return $clean ;
}
?>
< form action =
" <?php echo $_SERVER['PHP_SELF'];?> " method = " post " >
< p >< label for = " name " > Name </ label >
< input type =
" text " name = " name " id = " name " size = " 20 " maxlength = " 40 " /></ p >
< p >< input type = " submit " name = " submit " value = " go " /></ p >
</ form >
从安全的角度来看,对公共用户输入使用 strip_tags()
是必要的。如果表单在受保护区域(比如内容管理系统)中,而且您相信用户会正确地执行他们的任务(比如为 Web 站点创建 HTML 内容),那么使用 strip_tags()
可能是不必要的,会影响工作效率。
还有一个问题:如果要接受用户输入,比如对贴子的评论或来客登记项,并需要将这个输入向其他用户显示,那么一定要将响应放在 PHP 的 htmlspecialchars()
函数中。这个函数将与符号、<
和 >
符号转换为 HTML 实体。例如,与符号(&
)变成 &
。这样的话,即使恶意内容躲开了前端 strip_tags()
的处理,也会在后端被 htmlspecialchars()
处理掉。