$v) { if (is_array($v)) { $data[$k] = sanitizeInputArrayAdvanced($v, $htmlAllowedFields); continue; } if (!is_string($v)) { continue; } // 1. Unicode normalization (prevents homoglyph attacks) if (class_exists('Normalizer')) { $v = \Normalizer::normalize($v, \Normalizer::FORM_C); } // 2. Remove NULL bytes & control chars $v = preg_replace('/[\x00-\x1F\x7F]/u', '', $v); // 3. Remove invisible unicode chars (zero width, etc) $v = preg_replace('/[\x{200B}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{206F}]/u', '', $v); // 4. Decode HTML entities (so hidden payloads are exposed) $v = html_entity_decode($v, ENT_QUOTES | ENT_HTML5, 'UTF-8'); // 5. Trim $v = trim($v); // 6. If this field is NOT allowed to contain HTML → strip aggressively if (!in_array($k, $htmlAllowedFields, true)) { // Remove all tags $v = strip_tags($v); // Kill any leftover JS protocol $v = preg_replace('/(javascript:|data:|vbscript:)/i', '', $v); } else { // This is HTML-allowed field → run HTML sanitizer $v = sanitizeTrustedHtml($v); } $data[$k] = $v; } return $data; } function sanitizeTrustedHtml(string $html): string { // Allowed tags for email templates $allowedTags = '