132 lines
3.2 KiB
TypeScript
132 lines
3.2 KiB
TypeScript
/**
|
|
* 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[^>]*>.*?<\/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
|
|
} |