封装了一个类
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)