当前位置:首页 > PHP教程 > php应用 > 列表

PHP中HTML标签过滤的5种有效方法

发布:smiling 来源: PHP粉丝网  添加日期:2026-04-03 09:17:27 浏览: 评论:0 

什么是XSS攻击?

XSS(Cross-Site Scripting)攻击是指攻击者在网页中插入恶意脚本,当其他用户浏览该页面时,恶意脚本会被执行,从而盗取用户信息、会话令牌或进行其他恶意操作。

方法一:htmlspecialchars() - 最常用的转义方法

htmlspecialchars() 是PHP中最基本的XSS防护函数,它将特殊字符转换为HTML实体:

  1. <?php 
  2. $input = '<script>alert("XSS攻击")</script><p>正常内容</p>'
  3. $safe_output = htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); 
  4. echo $safe_output
  5. // 输出:&lt;script&gt;alert(&quot;XSS攻击&quot;)&lt;/script&gt;&lt;p&gt;正常内容&lt;/p&gt; 

参数详解:

ENT_QUOTES:转换双引号和单引号

UTF-8:指定字符编码,防止编码绕过攻击

适用场景: 纯文本输出,不需要保留任何HTML格式

方法二:strip_tags() - 彻底移除HTML标签

如果你确定不需要任何HTML标签,使用strip_tags()可以彻底移除它们:

  1. <?php 
  2. $input = '<script>alert("XSS")</script><p>正文内容</p><b>加粗文本</b>'
  3. $safe_output = strip_tags($input); 
  4. echo $safe_output
  5. // 输出:alert("XSS")正文内容加粗文本 

选择性保留标签:

  1. <?php 
  2. $input = '<script>alert("XSS")</script><p>正文</p><b>加粗</b><i>斜体</i>'
  3. $safe_output = strip_tags($input'<p><b>'); // 只保留<p>和<b>标签 
  4. echo $safe_output
  5. // 输出:<p>正文</p><b>加粗</b>斜体 

优点: 简单直接,性能好

缺点: 无法过滤标签内的属性

方法三:filter_var() - 使用PHP过滤器扩展

PHP过滤器扩展提供了更规范的过滤方式:

  1. <?php 
  2. $input = '<script>alert("XSS")</script><p>正常内容</p>'
  3. $safe_output = filter_var($input, FILTER_SANITIZE_STRING); 
  4. echo $safe_output
  5. // 输出:alert("XSS")正常内容 
  6.  
  7. // 专门用于过滤HTML 
  8. $html_output = filter_var($input, FILTER_SANITIZE_FULL_SPECIAL_CHARS); 

方法四:HTMLPurifier - 企业级解决方案

对于需要保留安全HTML内容的场景,HTMLPurifier是最佳选择:

安装方法:

composer require ezyang/htmlpurifier

使用示例:

  1. <?php 
  2. require_once 'vendor/autoload.php'
  3.  
  4. $config = HTMLPurifier_Config::createDefault(); 
  5. // 自定义配置 
  6. $config->set('HTML.Allowed''p,br,strong,em,ul,ol,li,a[href]'); 
  7. $config->set('AutoFormat.RemoveEmpty', true); 
  8.  
  9. $purifier = new HTMLPurifier($config); 
  10.  
  11. $input = '<script>alert("XSS")</script><p class="test">安全内容</p><a href="http://example.com" rel="external nofollow"  rel="external nofollow" >链接</a>'
  12. $safe_output = $purifier->purify($input); 
  13. echo $safe_output
  14. // 输出:<p>安全内容</p><a href="http://example.com" rel="external nofollow"  rel="external nofollow" >链接</a> 

优势:

遵循HTML标准

支持细粒度配置

能过滤危险的标签属性

社区活跃,持续更新

方法五:自定义过滤函数

针对特定需求,可以创建自定义过滤函数:

  1. <?php 
  2. function advanced_xss_clean($data) { 
  3.     if (emptyempty($data)) return ''
  4.       
  5.     // 递归处理数组 
  6.     if (is_array($data)) { 
  7.         return array_map('advanced_xss_clean'$data); 
  8.     } 
  9.       
  10.     // 移除NULL字节 
  11.     $data = str_replace(chr(0), ''$data); 
  12.       
  13.     // 转换特殊字符 
  14.     $data = htmlspecialchars($data, ENT_QUOTES | ENT_HTML5, 'UTF-8', true); 
  15.       
  16.     // 移除危险的JavaScript模式 
  17.     $patterns = [ 
  18.         '/javascript:/i'
  19.         '/vbscript:/i'
  20.         '/on\w+\s*=/i',    // 移除onclick等事件属性 
  21.         '/expression\s*\(/i' // 移除CSS表达式 
  22.     ]; 
  23.       
  24.     foreach ($patterns as $pattern) { 
  25.         $data = preg_replace($pattern''$data); 
  26.     } 
  27.       
  28.     return $data
  29.  
  30. // 使用示例 
  31. $input = '<img src="javascript:alert(1)" onclick="malicious()">'
  32. echo advanced_xss_clean($input); 
  33. ?> 

实战:根据不同场景选择防护策略

场景1:用户评论(允许有限HTML)

  1. <?php 
  2. function filter_comment($content) { 
  3.     $allowed_tags = '<p><br><strong><em><ul><ol><li><a>'
  4.     $content = strip_tags($content$allowed_tags); 
  5.       
  6.     // 进一步使用HTMLPurifier进行严格过滤 
  7.     require_once 'HTMLPurifier.auto.php'
  8.     $purifier = new HTMLPurifier(); 
  9.     return $purifier->purify($content); 
  10. ?> 

场景2:显示用户名(纯文本)

  1. <?php 
  2. function filter_username($username) { 
  3.     return htmlspecialchars(trim($username), ENT_QUOTES, 'UTF-8'); 
  4. ?> 

场景3:URL参数

  1. <?php 
  2. function filter_url($url) { 
  3.     $url = filter_var($url, FILTER_SANITIZE_URL); 
  4.     if (filter_var($url, FILTER_VALIDATE_URL)) { 
  5.         return htmlspecialchars($url, ENT_QUOTES, 'UTF-8'); 
  6.     } 
  7.     return ''
  8. ?> 

完整的安全防护示例

  1. <?php 
  2. class SecurityHelper { 
  3.       
  4.     public static function xss_clean($data$context = 'text') { 
  5.         if (emptyempty($data)) return $data
  6.           
  7.         if (is_array($data)) { 
  8.             return array_map([self::class'xss_clean'], $data); 
  9.         } 
  10.           
  11.         switch ($context) { 
  12.             case 'html'
  13.                 // 使用HTMLPurifier处理富文本 
  14.                 return self::purify_html($data); 
  15.                   
  16.             case 'attribute'
  17.                 // 用于HTML属性 
  18.                 return self::escape_attribute($data); 
  19.                   
  20.             case 'text'
  21.             default
  22.                 // 纯文本转义 
  23.                 return htmlspecialchars($data, ENT_QUOTES, 'UTF-8'); 
  24.         } 
  25.     } 
  26.       
  27.     private static function purify_html($html) { 
  28.         require_once 'HTMLPurifier.auto.php'
  29.         $config = HTMLPurifier_Config::createDefault(); 
  30.         $config->set('HTML.Allowed''p,br,strong,em,ul,ol,li,a[href|title]'); 
  31.         $purifier = new HTMLPurifier($config); 
  32.         return $purifier->purify($html); 
  33.     } 
  34.       
  35.     private static function escape_attribute($data) { 
  36.         return htmlspecialchars($data, ENT_QUOTES, 'UTF-8', false); 
  37.     } 
  38.  
  39. // 使用示例 
  40. $user_input = [ 
  41.     'username' => '<script>alert("xss")</script>'
  42.     'comment' => '<p>正常评论</p><script>恶意代码</script>'
  43.     'website' => 'javascript:alert(1)' 
  44. ]; 
  45.  
  46. $cleaned_data = SecurityHelper::xss_clean($user_input); 
  47. print_r($cleaned_data); 
  48. ?> 

防御深度建议

输入验证:在接收数据时进行严格验证

输出转义:根据输出上下文进行适当的转义

内容安全策略(CSP):设置HTTP头

header("Content-Security-Policy: default-src 'self'");

HttpOnly Cookie:防止Cookie被JavaScript读取

框架安全特性:优先使用框架提供的安全方法

总结

XSS防护是一个多层次的过程,需要根据具体场景选择合适的过滤策略:

纯文本输出:使用 htmlspecialchars()

完全移除HTML:使用 strip_tags()

保留安全HTML:使用 HTMLPurifier

企业级应用:结合多种方法,建立完整防护体系

记住:永远不要信任用户输入,在显示任何用户提供的数据之前,都要进行适当的过滤和转义。

Tags: PHP标签过滤 HTML标签过滤

分享到: