
Bibliothèque PHP qui assainit les fichiers SVG/XML non fiables en filtrant les balises, les attributs et les références distantes afin de prévenir les attaques XSS et l'injection de scripts dans les fichiers SVG téléversés ou intégrés en ligne.
Voici ma tentative de construire un assainisseur SVG correct en PHP. Le travail est en grande partie emprunté à DOMPurify.
Soit requérez enshrined/svg-sanitize via composer, soit téléchargez le dépôt et incluez-le à l'ancienne !
L'utilisation est assez simple. Créez une nouvelle instance de enshrined\svgSanitize\Sanitizer puis appelez la méthode sanitize en lui passant votre SVG/XML non assaini
Exemple basique
use enshrined\svgSanitize\Sanitizer;
// Create a new sanitizer instance
$sanitizer = new Sanitizer();
// Load the dirty svg
$dirtySVG = file_get_contents('filthy.svg');
// Pass it to the sanitizer and get it back clean
$cleanSVG = $sanitizer->sanitize($dirtySVG);
// Now do what you want with your clean SVG/XML data
Cela renvoie soit une chaîne SVG/XML assainie, soit le booléen false si l'analyse XML a échoué (généralement en raison d'un fichier mal formaté).
Elle renvoie également false pour les entrées qu'elle ne transmettra pas à l'analyseur XML :
<svg> dans un espace de noms autre que SVGgetXmlIssues() indique pourquoi.
Vous pouvez fournir votre propre liste blanche de balises et d'attributs en utilisant respectivement les méthodes Sanitizer::setAllowedTags et Sanitizer::setAllowedAttrs.
Ces méthodes exigent que vous implémentiez enshrined\svgSanitize\data\TagInterface ou enshrined\svgSanitize\data\AttributeInterface.
<use> est autorisé par défaut, sous réserve de limites sur l'étendue de l'expansion des références (useThreshold()) et de leur imbrication (setUseNestingLimit()). Si vous n'en avez pas besoin, par exemple parce que vous intégrez du SVG non fiable directement dans vos pages, retirez use de votre liste blanche de balises pour éliminer tout ce pan.
Vous avez la possibilité de supprimer les attributs qui référencent des fichiers distants ; cela empêchera les fuites HTTP mais ajoutera une surcharge au sanitizer.
Cette option est désactivée par défaut ; passez-la à true pour supprimer les références.
$sanitizer->removeRemoteReferences(true);
Lorsqu'elle est activée, les références distantes sont également supprimées du CSS à l'intérieur des éléments <style> et du CSS présent dans les attributs (url(), @import, image-set(), et les chaînes entre guillemets qui commencent par une URL distante). Les attributs srcset sont entièrement supprimés, car ils contiennent une liste d'URL. Ce traitement du CSS est effectué au mieux : ce n'est pas un analyseur CSS complet. Considérez-le comme une défense en profondeur plutôt qu'une garantie, et isolez le CSS non fiable à l'endroit où le SVG est intégré.
Remarque : si un élément <style> ou un attribut style contient une référence distante qui est supprimée, toutes les séquences d'échappement CSS de ce même bloc sont normalisées (décodées) dans la sortie. Le CSS est sémantiquement identique, mais les échappements écrits à la main par un auteur seront réécrits.
Vous pouvez utiliser la méthode getXmlIssues() pour renvoyer un tableau des problèmes survenus lors de l'assainissement.
Cela peut être utile pour la journalisation ou pour expliquer à l'utilisateur pourquoi un SVG a été refusé.
$issues = $sanitizer->getXmlIssues();
La liste contient jusqu'à 1 000 problèmes. S'il y en a davantage, la dernière entrée indique combien ont été omis.
Vous pouvez minifier la sortie XML en appelant $sanitizer->minify(true);.
Une démo est disponible à l'adresse : http://svg.enshrined.co.uk/
Je viens de publier une extension WordPress contenant ce code afin que vous puissiez assainir vos téléversements WordPress. Elle est disponible dans le répertoire des extensions WordPress : https://wordpress.org/plugins/safe-svg/
Michael Potter a aimablement créé un module Drupal pour cette bibliothèque, disponible à l'adresse : https://www.drupal.org/project/svg_sanitizer
Cette bibliothèque d'assainissement SVG est utilisée par défaut dans le cœur de TYPO3 v9 et des versions ultérieures. Voir l'entrée de journal des modifications correspondante pour plus de détails.
Vous pouvez les exécuter en lançant vendor/bin/phpunit depuis le répertoire de base de ce paquet.
Grâce au travail de gudmdharalds, il existe désormais un scanner autonome utilisable via la CLI.
Toute erreur sera affichée au format JSON. Voir la PR pour un exemple.
Utilisez-le comme suit : php svg-scanner.php ~/svgs/myfile.svg
Des tests plus approfondis pour les SVG/XML seraient les bienvenus ; je vais essayer de les ajouter bientôt. Si vous souhaitez le faire pour moi, n'hésitez pas et faites une PR !