[SÉCURITÉ] 7 min de lecture

[SÉCURITÉ] Bonnes Pratiques de Sécurité Base64

Considérations de sécurité importantes lors du travail avec l'encodage Base64 dans les applications web.

Janvier 2025 | security

// BASE64 N'EST PAS DU CHIFFREMENT

L'idée fausse la plus critique en matière de sécurité est de traiter Base64 comme du chiffrement. Base64 est simplement un encodage - il est complètement réversible sans aucune clé ou mot de passe.

N'importe qui peut décoder les données Base64 instantanément. Ne comptez jamais sur Base64 pour la sécurité ou la protection des données.

// ❌ FAUX : Utiliser Base64 comme 'sécurité'
const password = 'secret123';
const encoded = btoa(password); // c2VjcmV0MTIz
// N'importe qui peut décoder cela instantanément !

// ✅ CORRECT : Hachage de mot de passe approprié
import bcrypt from 'bcrypt';
const password = 'secret123';
const hashedPassword = await bcrypt.hash(password, 12);
// Ceci est réellement sécurisé

// VALIDATION D'ENTRÉE

Validez toujours l'entrée Base64 pour prévenir les attaques par injection et les erreurs d'application :

Une validation appropriée empêche les entrées malveillantes de causer des problèmes de sécurité ou des crashes d'application.

// Valider le format Base64
function isValidBase64(str) {
    // Vérifier le format : seulement des caractères Base64 valides
    const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
    if (!base64Regex.test(str)) {
        return false;
    }
    
    // Vérifier la longueur (doit être un multiple de 4)
    if (str.length % 4 !== 0) {
        return false;
    }
    
    // Tester le décodage
    try {
        atob(str);
        return true;
    } catch (e) {
        return false;
    }
}

// Décodage sécurisé avec validation
function safeBase64Decode(input, maxLength = 10000) {
    if (typeof input !== 'string') {
        throw new Error('L\'entrée doit être une chaîne');
    }
    
    if (input.length > maxLength) {
        throw new Error('Entrée trop longue');
    }
    
    if (!isValidBase64(input)) {
        throw new Error('Base64 invalide');
    }
    
    return atob(input);
}

// PRÉVENTION XSS

Les données Base64 peuvent contenir des scripts malveillants une fois décodées. Désinfectez toujours la sortie lors de l'affichage du contenu décodé :

Ne faites jamais confiance à l'entrée Base64 des utilisateurs. Désinfectez toujours avant de rendre dans le HTML.

// ❌ DANGEREUX : Injection HTML directe
function displayDecodedData(base64) {
    const decoded = atob(base64);
    document.innerHTML = decoded; // Vulnérabilité XSS !
}

// ✅ SÛR : Désinfecter la sortie
function safeDisplayDecodedData(base64) {
    const decoded = atob(base64);
    
    // Créer un nœud de texte (aucune exécution HTML)
    const textNode = document.createTextNode(decoded);
    container.appendChild(textNode);
    
    // Ou échapper les entités HTML
    const escaped = decoded
        .replace(/&/g, '&')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#x27;');
    
    container.innerHTML = escaped;
}

// LIMITES DE TAILLE

L'encodage Base64 augmente la taille des données d'environ 33%. Implémentez des limites de taille pour prévenir les attaques DoS :

Les entrées Base64 non restreintes peuvent consommer une mémoire et une puissance de traitement excessives.

  • > Définir des limites de longueur d'entrée maximales
  • > Surveiller l'utilisation de la mémoire pendant le traitement
  • > Implémenter des timeouts pour les opérations longues
  • > Utiliser le streaming pour les gros jeux de données
  • > Considérer la compression avant l'encodage
  • > Limiter le taux des opérations Base64

// GESTION SÉCURISÉE DES JETONS

Lors de l'utilisation de Base64 pour les jetons ou IDs sensibles, suivez les bonnes pratiques de sécurité :

Une gestion appropriée des jetons prévient l'accès non autorisé et les attaques basées sur les jetons.

// Création de jeton sécurisé
function createSecureToken() {
    // Utiliser des valeurs aléatoires cryptographiquement sûres
    const array = new Uint8Array(32);
    crypto.getRandomValues(array);
    
    // Convertir en Base64 et rendre sûr pour les URLs
    const base64 = btoa(String.fromCharCode(...array))
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '');
    
    return base64;
}

// Validation sécurisée de jeton
function validateToken(token, expectedLength = 43) {
    if (typeof token !== 'string') {
        return false;
    }
    
    // Vérifier la longueur
    if (token.length !== expectedLength) {
        return false;
    }
    
    // Vérifier le format Base64 sûr pour les URLs
    const urlSafeBase64Regex = /^[A-Za-z0-9_-]+$/;
    return urlSafeBase64Regex.test(token);
}

// SÉCURITÉ DES URI DE DONNÉES

Les URIs de données Base64 peuvent contenir du contenu malveillant. Validez et désinfectez toujours les URIs de données :

Les URIs de données malveillants peuvent exécuter des scripts, charger des ressources externes ou contenir du contenu inapproprié.

// Valider l'URI de données
function validateDataURI(dataUri, allowedTypes = ['image/png', 'image/jpeg']) {
    const dataUriRegex = /^data:([a-zA-Z0-9][a-zA-Z0-9\/+]*);base64,(.+)$/;
    const match = dataUri.match(dataUriRegex);
    
    if (!match) {
        throw new Error('Format d\'URI de données invalide');
    }
    
    const [, mimeType, base64Data] = match;
    
    // Valider le type MIME
    if (!allowedTypes.includes(mimeType)) {
        throw new Error(`Type MIME non supporté : ${mimeType}`);
    }
    
    // Valider les données Base64
    if (!isValidBase64(base64Data)) {
        throw new Error('Base64 invalide dans l\'URI de données');
    }
    
    // Vérifier la taille
    const sizeEstimate = (base64Data.length * 3) / 4;
    if (sizeEstimate > 1024 * 1024) { // Limite 1MB
        throw new Error('URI de données trop volumineux');
    }
    
    return { mimeType, base64Data };
}

// LISTE DE CONTRÔLE D'IMPLÉMENTATION SÉCURISÉE

  • > N'utilisez jamais Base64 comme mesure de chiffrement ou de sécurité
  • > Validez toujours le format et la longueur d'entrée Base64
  • > Désinfectez la sortie décodée avant l'affichage
  • > Implémentez des limites de taille et des timeouts
  • > Utilisez Base64 sûr pour les URLs pour les applications web
  • > Validez les types MIME pour les URIs de données
  • > Utilisez des valeurs aléatoires cryptographiquement sûres pour les jetons
  • > Implémentez une gestion d'erreur appropriée
  • > Surveillez les attaques DoS potentielles
  • > Audits de sécurité réguliers du code de gestion Base64