# Autoriser le SVG dans la médiathèque sans ouvrir une faille

> Un client graphiste qui ne peut pas importer ses logos en SVG, c'est frustrant. Mais autoriser le format sans le nettoyer ouvre une porte aux scripts malveillants.

- Auteur : Clément Hadrot
- Publié le : 2021-11-22
- Mis à jour le : 2021-11-22
- Catégorie : Tips
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/autoriser-svg-mediatheque-sans-faille/

## L’essentiel

- upload_mimes ne fait qu'autoriser l'extension
- Un SVG non nettoyé peut contenir du JavaScript
- Une bibliothèque de sanitization reste indispensable

Un studio de design partenaire d'une agence me demande régulièrement la même chose : pouvoir importer ses logos vectoriels directement dans la médiathèque, sans repasser par un export PNG à chaque révision. WordPress refuse le SVG par défaut, et c'est un choix assumé : un fichier SVG est en réalité un document XML, capable d'embarquer du JavaScript exécutable dans le navigateur. L'autoriser sans précaution revient à ouvrir une porte au cross-site scripting.

La bonne pratique combine deux étapes bien distinctes : autoriser techniquement le type MIME avec `upload_mimes`, puis nettoyer réellement le contenu du fichier avec une bibliothèque de sanitization dédiée. La première étape sans la seconde ne protège absolument rien.

## Autoriser le type MIME avec upload_mimes

Le filtre `upload_mimes` reçoit un tableau associant des extensions à des types MIME. Ajouter le SVG suffit pour que WordPress accepte le fichier au moment de l'upload, sans en vérifier le contenu.

```
function studio_autoriser_svg( $mimes ) {
    $mimes['svg'] = 'image/svg+xml';
    return $mimes;
}
add_filter( 'upload_mimes', 'studio_autoriser_svg' );
```

À ce stade, n'importe quel fichier `.svg` passe, y compris un fichier contenant une balise `<script>` ou un attribut `onload`. C'est précisément la raison pour laquelle WordPress refuse ce format par défaut : la vérification native basée sur `wp_check_filetype()` ne fait qu'inspecter l'extension et le type MIME déclaré, pas la structure interne du fichier.

## Nettoyer réellement le fichier avec une sanitization

Le hook `wp_handle_upload_prefilter` permet d'intercepter le fichier avant son enregistrement définitif, et donc d'y appliquer un nettoyage. La bibliothèque PHP `enshrined/svg-sanitize` est une référence largement utilisée dans l'écosystème WordPress pour cet usage précis : elle retire les balises et attributs dangereux tout en conservant le rendu visuel.

> L'essentiel à retenir : upload_mimes ne fait qu'autoriser l'extension ; Un SVG non nettoyé peut contenir du JavaScript ; Une bibliothèque de sanitization reste indispensable

```
function studio_nettoyer_svg_uploade( $file ) {
    if ( 'image/svg+xml' !== $file['type'] ) {
        return $file;
    }

    $contenu = file_get_contents( $file['tmp_name'] );

    $nettoyeur = new enshrined\svgSanitize\Sanitizer();
    $contenu_propre = $nettoyeur->sanitize( $contenu );

    if ( false === $contenu_propre ) {
        $file['error'] = 'Le fichier SVG n\'a pas pu être nettoyé.';
        return $file;
    }

    file_put_contents( $file['tmp_name'], $contenu_propre );
    return $file;
}
add_filter( 'wp_handle_upload_prefilter', 'studio_nettoyer_svg_uploade' );
```

Cette bibliothèque se déclare via Composer (`composer require enshrined/svg-sanitize`) et se charge à travers l'autoloader du thème ou de l'extension maison. Sans gestionnaire de dépendances, une version packagée en fichier unique existe aussi, mais Composer reste préférable pour suivre les mises à jour de sécurité.

## Restreindre l'upload par rôle

Même nettoyé, il reste prudent de restreindre l'upload de SVG aux rôles de confiance — administrateurs et éditeurs — plutôt que de l'ouvrir à tous les contributeurs d'un site à plusieurs mains.

```
function studio_autoriser_svg( $mimes ) {
    if ( ! current_user_can( 'manage_options' ) ) {
        return $mimes;
    }
    $mimes['svg'] = 'image/svg+xml';
    return $mimes;
}
add_filter( 'upload_mimes', 'studio_autoriser_svg' );
```

## Générer une miniature correcte dans la médiathèque

Sans traitement supplémentaire, un fichier SVG s'affiche comme une icône générique grise dans la grille de la médiathèque, ce qui complique la sélection visuelle. Un filtre sur `wp_prepare_attachment_for_js` permet d'utiliser le fichier SVG lui-même comme miniature, puisque le format s'affiche nativement dans un navigateur.

```
function studio_miniature_svg( $reponse, $attachment ) {
    if ( 'image/svg+xml' === $attachment->post_mime_type ) {
        $url = wp_get_attachment_url( $attachment->ID );
        $reponse['sizes']['thumbnail'] = array(
            'url'    => $url,
            'width'  => 150,
            'height' => 150,
        );
    }
    return $reponse;
}
add_filter( 'wp_prepare_attachment_for_js', 'studio_miniature_svg', 10, 2 );
```

> Je n'ai jamais rencontré de client qui refuse cette contrainte une fois expliquée : personne ne veut être responsable d'une faille XSS exploitée via le logo qu'il vient d'importer lui-même.

## En résumé

Autoriser le SVG sans le nettoyer n'est pas une demi-mesure : c'est une absence totale de protection, puisque `upload_mimes` ne fait qu'ouvrir la porte sans jamais inspecter le contenu. La sanitization via une bibliothèque dédiée, couplée à une restriction par rôle, transforme cette ouverture en fonctionnalité réellement sûre.
