/** * Utilitaires de sanitisation pour les entrées utilisateur côté frontend */ export class InputSanitizer { /** * Encode les entités HTML pour prévenir XSS */ static encodeHtml(input: string): string { if (!input) return input; const div = document.createElement('div'); div.textContent = input; return div.innerHTML; } /** * Supprime les balises HTML dangereuses */ static stripHtml(input: string): string { if (!input) return input; return input.replace(/<[^>]*>/g, ''); } /** * Sanitise un email */ static sanitizeEmail(email: string): string { if (!email) return email; return email.trim().toLowerCase(); } /** * Sanitise un nom/prénom */ static sanitizeName(name: string): string { if (!name) return name; // Supprimer les caractères dangereux let sanitized = name.replace(/[<>'"&]/g, ''); // Garder seulement les lettres, espaces, tirets et apostrophes sanitized = sanitized.replace(/[^a-zA-ZàáâäçéèêëíìîïñóòôöúùûüÿýÀÁÂÄÇÉÈÊËÍÌÎÏÑÓÒÔÖÚÙÛÜŸÝ\s'-]/g, ''); return sanitized.trim(); } /** * Sanitise un numéro de téléphone */ static sanitizePhone(phone: string): string { if (!phone) return phone; // Garder seulement les chiffres et le + au début return phone.replace(/[^0-9+]/g, ''); } /** * Sanitise une adresse */ static sanitizeAddress(address: string): string { if (!address) return address; // Supprimer les caractères dangereux let sanitized = address.replace(/[<>'"&]/g, ''); // Garder les caractères alphanumériques et ponctuation courante sanitized = sanitized.replace(/[^a-zA-Z0-9àáâäçéèêëíìîïñóòôöúùûüÿýÀÁÂÄÇÉÈÊËÍÌÎÏÑÓÒÔÖÚÙÛÜŸÝ\s,.-]/g, ''); return sanitized.trim(); } /** * Valide qu'une entrée ne contient pas de code malveillant */ static isInputSafe(input: string): boolean { if (!input) return true; const dangerousPatterns = [ /]*>.*?<\/script>/gi, /javascript:/gi, /vbscript:/gi, /onload=/gi, /onerror=/gi, /onclick=/gi, /onmouseover=/gi, /eval\(/gi, /expression\(/gi, ]; return !dangerousPatterns.some(pattern => pattern.test(input)); } /** * Sanitise une entrée générique */ static sanitize(input: string): string { if (!input) return input; // Supprimer les balises HTML let sanitized = this.stripHtml(input); // Encoder les entités HTML sanitized = this.encodeHtml(sanitized); return sanitized.trim(); } } /** * Hook React pour la sanitisation automatique des inputs */ export function useSanitizedInput(initialValue: string = '') { const [value, setValue] = React.useState(initialValue); const setSanitizedValue = (newValue: string) => { const sanitized = InputSanitizer.sanitize(newValue); setValue(sanitized); }; return [value, setSanitizedValue] as const; } // Import React pour le hook (si disponible) let React: any; try { React = require('react'); } catch (e) { // React non disponible, le hook ne sera pas utilisable }