| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- <?php
- namespace BCJD;
- /**
- * Validator - 输入验证与净化
- *
- * 安全特性:
- * - HTML 转义(XSS 防护)
- * - URL 格式校验
- * - 字符串长度限制
- * - 白名单样式类校验
- */
- class Validator
- {
- /**
- * HTML 转义(XSS 防护)
- */
- public static function escape(string $value): string
- {
- return htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
- }
- /**
- * 净化 URL(仅允许 http/https 协议)
- */
- public static function sanitizeUrl(string $url): string
- {
- $url = trim($url);
- // 禁止 javascript: data: 等危险协议
- if (preg_match('/^(javascript|data|file|php):/i', $url)) {
- return '';
- }
- // 自动补全协议
- if (!preg_match('#^https?://#i', $url)) {
- $url = 'https://' . $url;
- }
- return filter_var($url, FILTER_VALIDATE_URL) !== false ? $url : '';
- }
- /**
- * SVG 净化:仅允许安全的 SVG 标签和属性
- */
- public static function sanitizeSvg(string $svg): string
- {
- // 只允许纯 SVG 标签(移除 script/style/foreignObject 等危险元素)
- $svg = strip_tags($svg, '<svg><path><circle><rect><line><polyline><polygon><ellipse><g><defs><use><text><tspan><stop><linearGradient><radialGradient><filter><feGaussianBlur><feOffset><feColorMatrix><feBlend><feMerge><feMergeNode>');
- // 移除 on* 事件属性(如 onclick, onload, onerror)
- $svg = preg_replace('/\bon\w+\s*=\s*(["\']).*?\1/is', '', $svg);
- // 移除 href 属性(防止通过 href="javascript:..." 执行脚本)
- $svg = preg_replace('/\bhref\s*=\s*(["\']).*?\1/i', '', $svg);
- // 移除 xlink:href(同上)
- $svg = preg_replace('/\bxlink:href\s*=\s*(["\']).*?\1/i', '', $svg);
- return $svg;
- }
- /**
- * 验证分组名(英文+数字+下划线)
- */
- public static function validateGroupName(string $name): string
- {
- $name = trim($name);
- if (!preg_match('/^[a-zA-Z0-9_\-]{1,50}$/', $name)) {
- return 'default';
- }
- return $name;
- }
- /**
- * 白名单校验标签样式类
- */
- public static function validateTagClass(string $class): string
- {
- $allowed = ['', 'ok', 'warn'];
- return in_array($class, $allowed, true) ? $class : '';
- }
- /**
- * 截断字符串到指定长度
- */
- public static function truncate(string $value, int $maxLength = 255): string
- {
- return mb_substr(trim($value), 0, $maxLength, 'UTF-8');
- }
- /**
- * 净化关键字(移除特殊字符)
- */
- public static function sanitizeKeywords(string $keywords): string
- {
- return preg_replace('/[^\p{L}\p{N}\s\-_]/u', '', trim($keywords));
- }
- /**
- * 验证密码强度
- */
- public static function validatePassword(string $password): ?string
- {
- if (strlen($password) < 6) {
- return '密码至少需要6个字符';
- }
- if (strlen($password) > 128) {
- return '密码长度不能超过128个字符';
- }
- return null;
- }
- /**
- * 安全地清理用户输入:去除不可见控制字符
- */
- public static function stripControlChars(string $value): string
- {
- return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $value);
- }
- }
|