【PHP】过滤富文本内容

小破孩
2025-03-13 / 0 评论 / 86 阅读 / 正在检测是否收录...

封装了一个类

class TextFilter {
    // 定义要过滤的 SQL 关键字模式
    const SQL_PATTERNS = [
        '/\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|AND|OR|JOIN|DROP|CREATE|ALTER|TRUNCATE|GRANT|REVOKE|SET)\b/i',
        '/\b(AS|LIKE|NOT|IN|BETWEEN|IS|NULL|COUNT|SUM|AVG|MIN|MAX)\b/i',
        '/\b(UNION|ALL|ANY|EXISTS)\b/i',
        '/\b(ORDER\s+BY|LIMIT)\b/i'
    ];
    // 定义要过滤的常见函数模式
    const FUNCTION_PATTERNS = [
        '/\b(function\s+\w+\s*\([^)]*\))\b/i',
        '/\b(eval|exec|system|passthru|shell_exec|assert)\b/i'
    ];
    // 定义要过滤的特殊字符和表达式模式
    const SPECIAL_PATTERNS = [
        '/\$\{.*?\}/', // 过滤类似 ${expression} 的表达式
        '/@.*?;/', // 过滤以 @ 开头并以 ; 结尾的表达式
        '/\b(phpinfo|var_dump)\b/i', // 过滤特定的 PHP 函数
        '/<\s*(script|iframe|object|embed|applet)[^>]*>/i' // 过滤危险的脚本标签
    ];
    // 定义要过滤的危险属性模式
    const DANGEROUS_ATTRIBUTES_PATTERNS = [
        '/on\w+\s*=/i', // 过滤以 "on" 开头的事件属性
        '/javascript:[^"]*"/i' // 过滤 JavaScript 协议的链接
    ];

    /**
     * @Author:小破孩
     * @Email:3584685883@qq.com
     * @Time:2024/10/24 13:50
     * @param $text
     * @return string|string[]|null
     * @Description:过滤富文本
     */
    public static function filterRichText($text) {
        // 合并所有要过滤的模式
        $allPatterns = array_merge(
            self::SQL_PATTERNS,
            self::FUNCTION_PATTERNS,
            self::SPECIAL_PATTERNS,
            self::DANGEROUS_ATTRIBUTES_PATTERNS
        );

        // 先过滤所有匹配的模式
        $filteredText = preg_replace($allPatterns, '', $text);

        // 保留 <img> 标签,但需要确保 src 属性是安全的
        $filteredText = preg_replace_callback('/<img[^>]+>/i', [__CLASS__, 'filterImgTag'], $filteredText);

        // 允许表情符号和其他图标
        $filteredText = preg_replace('/[\x{1F600}-\x{1F64F}]|\x{1F300}-\x{1F5FF}|\x{1F680}-\x{1F6FF}|\x{2600}-\x{26FF}|\x{2700}-\x{27BF}/u', '$0', $filteredText);

        // 处理可能出现的连续空格
        $filteredText = preg_replace('/\s+/', ' ', $filteredText);
        // 去除前后的空格
        $filteredText = trim($filteredText);
        // 转换 HTML 实体
        $filteredText = htmlentities($filteredText, ENT_QUOTES, 'UTF-8');

        return $filteredText;
    }

    private static function filterImgTag($matches) {
        $imgTag = $matches[0];
        if (preg_match('/src=["\'](?<src>[^"\']+)["\']/i', $imgTag, $srcMatch)) {
            $src = $srcMatch['src'];
            // 这里可以进一步验证 src 是否是允许的 URL 或本地路径
            if (filter_var($src, FILTER_VALIDATE_URL) || strpos($src, '/') === 0) {
                return $imgTag;
            }
        }
        return '';
    }
}

// 示例调用
$text = '<script>alert("XSS")</script><img src="https://example.com/image.jpg">';
$filteredText = TextFilter::filterRichText($text);
echo $filteredText;    

函数 方法

    /**
     * @Author:小破孩
     * @Email:3584685883@qq.com
     * @Time:2024/10/24 13:50
     * @param $text
     * @return string|string[]|null
     * @Description:过滤富文本
     */
    public static function filterRichText($text){
        // 定义要过滤的 SQL 关键字模式
        $sqlPatterns = [
            '/\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|AND|OR|JOIN|DROP|CREATE|ALTER|TRUNCATE|GRANT|REVOKE|SET)\b/i',
            '/\b(AS|LIKE|NOT|IN|BETWEEN|IS|NULL|COUNT|SUM|AVG|MIN|MAX)\b/i',
            '/\b(UNION|ALL|ANY|EXISTS)\b/i',
            '/\b(ORDER\s+BY|LIMIT)\b/i'
        ];
        // 定义要过滤的常见函数模式
        $functionPatterns = [
            '/\b(function\s+\w+\s*\([^)]*\))\b/i',
            '/\b(eval|exec|system|passthru|shell_exec|assert)\b/i'
        ];
        // 定义要过滤的特殊字符和表达式模式
        $specialPatterns = [
            '/\$\{.*?\}/', // 过滤类似 ${expression} 的表达式
            '/@.*?;/', // 过滤以 @ 开头并以 ; 结尾的表达式
            '/\b(phpinfo|var_dump)\b/i', // 过滤特定的 PHP 函数
            '/<\s*(script|iframe|object|embed|applet)[^>]*>/i' // 过滤危险的脚本标签
        ];
        // 定义要过滤的危险属性模式
        $dangerousAttributesPatterns = [
            '/on\w+\s*=/i', // 过滤以 "on" 开头的事件属性
            '/javascript:[^"]*"/i' // 过滤 JavaScript 协议的链接
        ];
        // 先过滤 SQL 关键字
        $filteredText = preg_replace($sqlPatterns, '', $text);
        // 再过滤函数
        $filteredText = preg_replace($functionPatterns, '', $filteredText);
        // 然后过滤特殊字符和表达式
        $filteredText = preg_replace($specialPatterns, '', $filteredText);
        // 接着过滤危险的属性
        $filteredText = preg_replace($dangerousAttributesPatterns, '', $filteredText);
        // 允许表情符号和其他图标
        $filteredText = preg_replace('/[\x{1F600}-\x{1F64F}]|\x{1F300}-\x{1F5FF}|\x{1F680}-\x{1F6FF}|\x{2600}-\x{26FF}|\x{2700}-\x{27BF}/u', '$0', $filteredText);
        // 处理可能出现的连续空格
        $filteredText = preg_replace('/\s+/', ' ', $filteredText);
        // 去除前后的空格
        $filteredText = trim($filteredText);
        // 转换 HTML 实体
        $filteredText = htmlentities($filteredText, ENT_QUOTES, 'UTF-8');

        return $filteredText;
    }

    /**
 * @Author:小破孩
 * @Email:3584685883@qq.com
 * @Time:2024/10/24 13:50
 * @param $text
 * @return string|string[]|null
 * @Description:过滤富文本
 */
function filterRichText($text) {
    // 合并所有要过滤的模式
    $patterns = [
        '/\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|AND|OR|JOIN|DROP|CREATE|ALTER|TRUNCATE|GRANT|REVOKE|SET)\b/i',
        '/\b(AS|LIKE|NOT|IN|BETWEEN|IS|NULL|COUNT|SUM|AVG|MIN|MAX)\b/i',
        '/\b(UNION|ALL|ANY|EXISTS)\b/i',
        '/\b(ORDER\s+BY|LIMIT)\b/i',
        '/\b(function\s+\w+\s*\([^)]*\))\b/i',
        '/\b(eval|exec|system|passthru|shell_exec|assert)\b/i',
        '/\$\{.*?\}/',
        '/@.*?;/',
        '/\b(phpinfo|var_dump)\b/i',
        '/<\s*(script|iframe|object|embed|applet)[^>]*>/i',
        '/on\w+\s*=/i',
        '/javascript:[^"]*"/i'
    ];

    // 先过滤所有匹配的模式
    $filteredText = preg_replace($patterns, '', $text);

    // 允许表情符号和其他图标
    $filteredText = preg_replace('/[\x{1F600}-\x{1F64F}]|\x{1F300}-\x{1F5FF}|\x{1F680}-\x{1F6FF}|\x{2600}-\x{26FF}|\x{2700}-\x{27BF}/u', '$0', $filteredText);

    // 处理可能出现的连续空格
    $filteredText = preg_replace('/\s+/', ' ', $filteredText);

    // 去除前后的空格
    $filteredText = trim($filteredText);

    // 转换 HTML 实体
    $filteredText = htmlentities($filteredText, ENT_QUOTES, 'UTF-8');

    return $filteredText;
}

// 示例调用
$text = '<script>alert("XSS")</script><img src="https://example.com/image.jpg">';
$filteredText = filterRichText($text);
echo $filteredText;
0

评论 (0)

取消