En-têtes Content Security Policy pour PrestaShop
Qu'est-ce que la Content Security Policy et pourquoi c'est important
La Content Security Policy (CSP) est un mécanisme de sécurité implémenté via des en-têtes HTTP qui indique au navigateur exactement quelles ressources sont autorisées à se charger sur vos pages. Elle empêche les attaques de type cross-site scripting (XSS), les attaques par injection de données et autres vulnérabilités d'injection de code en vous donnant un contrôle granulaire sur l'origine du JavaScript, du CSS, des images, des polices, des frames et d'autres ressources.
Sans CSP, un navigateur exécute tout JavaScript qu'il rencontre sur votre page, quelle que soit sa provenance. Si un attaquant parvient à injecter un code malveillant (via un module vulnérable, une bibliothèque tierce compromise ou une vulnérabilité XSS persistante), le navigateur l'exécute volontiers avec un accès complet au contenu de la page, y compris les données clients, les entrées de formulaires et les cookies de session.
Avec CSP, vous déclarez une liste blanche de sources de confiance. Si le navigateur rencontre une ressource qui ne correspond pas à la politique, il la bloque et journalise une violation. Cela signifie que même si un attaquant trouve un moyen d'injecter du code dans votre page, le navigateur refuse de l'exécuter car il ne provient pas d'une source approuvée.
Pour les boutiques PrestaShop qui traitent les informations personnelles des clients, les données de paiement et les identifiants d'authentification, la CSP est une couche de sécurité critique. Ce n'est pas un remplacement pour la correction des vulnérabilités dans votre code, mais c'est une mesure de défense en profondeur efficace qui limite les dégâts lorsqu'une vulnérabilité existe.
Les directives CSP expliquées
Une Content Security Policy est composée d'une ou plusieurs directives, chacune contrôlant un type spécifique de ressource. Les directives les plus importantes pour PrestaShop sont :
default-src : La directive de repli. Si une directive plus spécifique n'est pas définie, le navigateur utilise default-src. Définir default-src 'self' signifie que par défaut, seules les ressources de votre propre domaine sont autorisées.
script-src : Contrôle d'où le JavaScript peut être chargé. C'est la directive la plus critique pour la prévention XSS. Les valeurs courantes incluent 'self' (votre propre domaine), des domaines CDN spécifiques et des domaines analytics.
style-src : Contrôle d'où le CSS peut être chargé. Les thèmes et modules PrestaShop utilisent fréquemment des styles en ligne, ce qui signifie que vous pourriez avoir besoin de 'unsafe-inline' sauf si vous implémentez une approche basée sur les nonces.
img-src : Contrôle d'où les images peuvent être chargées. Les boutiques PrestaShop chargent souvent des images depuis leur propre domaine, des domaines CDN et des services tiers comme Google (pour les avatars utilisateur ou Maps).
font-src : Contrôle d'où les polices peuvent être chargées. Google Fonts, Font Awesome CDN et votre propre domaine sont des sources courantes.
connect-src : Contrôle quelles URLs peuvent être contactées via JavaScript (requêtes AJAX, connexions WebSocket, EventSource). Les passerelles de paiement, les points de terminaison analytics et vos propres points de terminaison API doivent être listés ici.
frame-src : Contrôle quels domaines peuvent être intégrés dans des iframes. Les passerelles de paiement comme PayPal, Stripe et Klarna utilisent des iframes pour leurs formulaires de paiement. Les intégrations YouTube et Vimeo nécessitent également des entrées frame-src.
frame-ancestors : Contrôle quels domaines peuvent intégrer votre page dans un iframe. Définir frame-ancestors 'self' empêche les attaques de clickjacking en garantissant que votre boutique ne peut pas être intégrée dans l'iframe d'un autre site.
object-src : Contrôle le contenu de plugins comme Flash. Définissez-le sur 'none' car Flash est obsolète et aucune fonctionnalité PrestaShop ne le nécessite.
base-uri : Contrôle quelles URLs peuvent être utilisées dans l'élément <base>. Définissez-le sur 'self' pour empêcher les attaques de manipulation de base URI.
form-action : Contrôle vers quelles URLs les formulaires peuvent être soumis. Cela devrait inclure votre propre domaine et tous les points de terminaison de traitement de paiement externes.
Commencer avec le mode Report-Only
Le déploiement de CSP sur une boutique PrestaShop nécessite une préparation soigneuse car une politique trop restrictive cassera des fonctionnalités. La bonne approche est de commencer en mode report-only, qui dit au navigateur de rapporter les violations sans rien bloquer réellement.
Au lieu d'utiliser l'en-tête Content-Security-Policy, utilisez Content-Security-Policy-Report-Only. Cet en-tête accepte exactement les mêmes directives mais ne génère que des rapports sans appliquer la politique. Votre boutique continue de fonctionner normalement pendant que vous collectez des données sur ce qui serait bloqué.
Configurer le rapport de violations
Ajoutez une directive report-uri à votre politique pointant vers un point de terminaison qui collecte les rapports de violations. Vous pouvez utiliser un service gratuit comme Report URI (report-uri.com), qui fournit un tableau de bord pour visualiser et analyser les violations CSP, ou vous pouvez configurer votre propre point de terminaison.
Le navigateur envoie les rapports de violations sous forme de requêtes POST JSON. Chaque rapport inclut l'URI bloquée, la directive violée, la page où la violation s'est produite et d'autres informations de débogage utiles. Collecter ces rapports pendant une à deux semaines sur une boutique en production vous donne une image complète de toutes les ressources que votre boutique charge et d'où elles proviennent.
Construire votre politique initiale
En utilisant les rapports de violations du mode report-only, construisez une liste blanche de toutes les sources de ressources légitimes. Regroupez-les par type de directive. Votre politique initiale inclura probablement :
Votre propre domaine pour tous les types de ressources. Les domaines CDN (comme cdnjs.cloudflare.com, fonts.googleapis.com, fonts.gstatic.com) pour les scripts, styles et polices. Les domaines analytics (comme google-analytics.com, googletagmanager.com, connect.facebook.net) pour le suivi. Les domaines de passerelles de paiement pour les scripts, frames et connexions. Les domaines de widgets de chat si vous utilisez le chat en direct. Les domaines de réseaux sociaux pour le contenu intégré ou les boutons de partage.
Construire une CSP pour PrestaShop
PrestaShop présente des défis spécifiques pour l'implémentation CSP en raison de son architecture et de l'écosystème de modules.
Gérer les styles et scripts en ligne
Le cœur de PrestaShop, les thèmes et de nombreux modules utilisent largement les styles en ligne et le JavaScript en ligne. Le code en ligne est bloqué par défaut dans CSP car un attaquant qui injecte du contenu dans votre page injecterait du code en ligne. Il y a trois approches pour gérer cela :
Utiliser 'unsafe-inline' : L'approche la plus simple mais la moins sûre. Ajouter 'unsafe-inline' à script-src et style-src autorise tout le code en ligne, ce qui affaiblit significativement la protection XSS de CSP. Pour style-src, c'est généralement acceptable car les styles en ligne posent un risque de sécurité beaucoup plus faible que les scripts en ligne. Pour script-src, évitez 'unsafe-inline' autant que possible.
Utiliser des nonces : L'approche recommandée. Un nonce est un jeton aléatoire à usage unique généré à chaque requête. Vous ajoutez le nonce à votre en-tête CSP (script-src 'nonce-abc123') et à chaque balise script en ligne légitime (<script nonce="abc123">). Le navigateur n'exécute que les scripts en ligne ayant le nonce correct. Comme le nonce change à chaque requête et qu'un attaquant ne peut pas le prédire, les scripts injectés sans le nonce sont bloqués.
Implémenter des nonces dans PrestaShop nécessite de modifier le thème pour ajouter des attributs nonce à toutes les balises script en ligne et de créer un mécanisme (typiquement un module ou un hook personnalisé) qui génère le nonce, l'ajoute à l'en-tête CSP et le rend disponible aux templates. C'est un effort d'implémentation significatif mais fournit une forte protection XSS.
Utiliser des hashes : Vous pouvez mettre en liste blanche des scripts en ligne spécifiques par leur hash SHA-256. Le navigateur calcule le hash de chaque script en ligne qu'il rencontre et le vérifie contre les hashes listés dans le CSP. Cette approche fonctionne pour les scripts en ligne qui ne changent pas entre les requêtes (scripts en ligne statiques), mais elle est impraticable pour PrestaShop car de nombreux scripts en ligne incluent du contenu dynamique comme des identifiants produit, des prix et des données spécifiques à l'utilisateur qui changent le hash.
Gérer eval et le code dynamique
Certaines bibliothèques JavaScript utilisent eval() ou new Function() pour créer et exécuter dynamiquement du code. CSP les bloque par défaut. Si un module ou une bibliothèque nécessite eval, vous devez ajouter 'unsafe-eval' à script-src. Les coupables courants incluent les anciennes versions de templates jQuery, certains scripts analytics et certaines bibliothèques de passerelles de paiement.
Vérifiez vos rapports de violations pour les entrées avec eval ou inline comme URI bloquée. Celles-ci indiquent du code utilisant l'évaluation dynamique. Lorsque possible, remplacez la bibliothèque par une version qui n'utilise pas eval. Quand ce n'est pas possible (comme avec une bibliothèque de passerelle de paiement tierce que vous ne pouvez pas modifier), 'unsafe-eval' est la seule option.
Services tiers
La plupart des boutiques PrestaShop dépendent de multiples services tiers, chacun devant être ajouté à la liste blanche de votre CSP. Voici les plus courants et les directives qu'ils nécessitent :
Google Analytics et Google Tag Manager : Ceux-ci nécessitent des entrées dans script-src pour www.google-analytics.com, www.googletagmanager.com et tagmanager.google.com. Ils ont aussi besoin d'entrées connect-src pour www.google-analytics.com et analytics.google.com (pour envoyer les données de suivi), et d'entrées img-src pour www.google-analytics.com (pour le pixel de suivi). Google Tag Manager est particulièrement difficile car il charge dynamiquement des scripts depuis des domaines que vous ne connaissez peut-être pas à l'avance, car les scripts chargés dépendent des balises configurées dans GTM.
PayPal : Nécessite des entrées script-src et frame-src pour *.paypal.com et *.paypalobjects.com. Les domaines exacts dépendent de si vous utilisez PayPal Standard, PayPal Express ou la plus récente intégration PayPal Commerce Platform.
Stripe : Nécessite script-src pour js.stripe.com, frame-src pour js.stripe.com et hooks.stripe.com, et connect-src pour api.stripe.com.
Google Fonts : Nécessite style-src pour fonts.googleapis.com et font-src pour fonts.gstatic.com.
Intégrations YouTube : Nécessitent frame-src pour www.youtube.com et www.youtube-nocookie.com.
Pixel Facebook et plugins sociaux : Nécessitent script-src et connect-src pour connect.facebook.net et www.facebook.com, plus img-src pour www.facebook.com et *.fbcdn.net.
Widgets de chat en direct (Tidio, Crisp, Intercom, etc.) : Chacun a son propre ensemble de domaines pour les scripts, styles, connexions WebSocket et images. Vérifiez vos rapports de violations ou la documentation du fournisseur pour les domaines exacts requis.
Un exemple CSP complet pour PrestaShop
Voici un en-tête CSP réaliste pour une boutique PrestaShop utilisant Google Analytics, Google Fonts, PayPal, les intégrations YouTube et ayant des styles en ligne :
Content-Security-Policy: default-src 'self'; script-src 'self' www.google-analytics.com www.googletagmanager.com js.stripe.com 'unsafe-inline' 'unsafe-eval'; style-src 'self' fonts.googleapis.com 'unsafe-inline'; img-src 'self' data: www.google-analytics.com *.paypal.com; font-src 'self' fonts.gstatic.com; connect-src 'self' www.google-analytics.com analytics.google.com api.stripe.com; frame-src 'self' www.youtube.com www.youtube-nocookie.com js.stripe.com *.paypal.com; frame-ancestors 'self'; object-src 'none'; base-uri 'self'; form-action 'self' *.paypal.com;
Cette politique inclut 'unsafe-inline' et 'unsafe-eval' pour les scripts, ce qui affaiblit la protection XSS mais est nécessaire pour la plupart des installations PrestaShop qui n'ont pas été modifiées pour supporter les nonces. Pour img-src, la source data: est incluse car PrestaShop et de nombreux modules utilisent des URI de données pour les petites images et icônes.
Implémenter CSP dans PrestaShop
Via .htaccess (Apache)
Pour les serveurs Apache, ajoutez l'en-tête CSP dans votre fichier .htaccess. Placez-le près du début du fichier, avant les règles de réécriture PrestaShop :
Header set Content-Security-Policy "default-src 'self'; script-src 'self' ..."
Cela nécessite que le module mod_headers soit activé. Vous pouvez vérifier si votre serveur retourne l'en-tête en utilisant les DevTools du navigateur (onglet Réseau, cliquer sur la requête du document principal, vérifier les en-têtes de réponse).
Via la configuration Nginx
Pour Nginx, ajoutez l'en-tête dans votre bloc serveur :
add_header Content-Security-Policy "default-src 'self'; script-src 'self' ..." always;
Le paramètre always garantit que l'en-tête est envoyé même pour les réponses d'erreur, ce qui est important car les pages d'erreur peuvent également être des cibles d'attaques XSS.
Via un module PrestaShop
Implémenter CSP via un module vous donne la possibilité de gérer la politique depuis le back-office. Le module se connecte au actionOutputHTMLBefore ou utilise la fonction header() de PHP dans un hook de contrôleur front pour ajouter l'en-tête CSP à chaque réponse. Une approche basée sur un module est plus facile à maintenir car vous pouvez mettre à jour la politique sans éditer les fichiers de configuration du serveur et sans redémarrer le serveur web.
Tester votre CSP avec les DevTools du navigateur
Après avoir implémenté votre CSP (en mode report-only initialement), utilisez les DevTools du navigateur pour surveiller les violations. Ouvrez l'onglet Console et cherchez les messages commençant par "[Report Only]" (en mode report-only) ou "Refused to" (en mode application). Chaque message vous indique exactement ce qui a été bloqué et quelle directive était responsable.
Testez chaque type de page de votre boutique : la page d'accueil, les pages de catégories, les pages produits, le panier, le processus de commande (y compris chaque étape et chaque méthode de paiement), les pages de compte client et les pages CMS. Chaque type de page peut charger des ressources différentes, et vous devez vous assurer que votre politique les couvre toutes.
Portez une attention particulière au processus de commande. Un script ou iframe de passerelle de paiement bloqué pendant le checkout empêche directement les clients de finaliser leurs achats. Testez chaque méthode de paiement que vous proposez, y compris le flux de vérification 3D Secure le cas échéant, car ceux-ci chargent souvent des ressources supplémentaires depuis des domaines qui ne sont pas évidents.
Pièges de test courants
Les tests dans un environnement de développement peuvent ne pas révéler toutes les violations car votre configuration de développement peut ne pas inclure tous les services tiers qui fonctionnent en production (analytics, pixels publicitaires, chat en direct, outils de tests A/B). Déployez toujours CSP en mode report-only sur la production d'abord et collectez des rapports pendant au moins une à deux semaines avant de passer à l'application.
Certaines violations ne se produisent que dans des conditions spécifiques. Par exemple, une passerelle de paiement pourrait charger des scripts de vérification supplémentaires uniquement lorsque la carte d'un client nécessite une authentification 3D Secure. Les boutons de partage social pourraient charger des scripts uniquement lorsqu'un visiteur clique dessus. Le contenu dynamique chargé via AJAX peut référencer des ressources qui ne sont pas présentes lors du chargement initial de la page. Parcourez chaque flux utilisateur possible pendant les tests.
Stratégie d'application progressive
La stratégie de déploiement recommandée pour CSP sur PrestaShop suit ces étapes :
Phase 1 : Découverte. Déployez un en-tête Content-Security-Policy-Report-Only permissif avec default-src * 'unsafe-inline' 'unsafe-eval' data: blob:; et un report-uri. Cela journalise toutes les ressources sans rien bloquer, vous donnant un inventaire complet de ce que votre boutique charge.
Phase 2 : Ébauche de politique. Basé sur les rapports de violations, construisez une politique de liste blanche couvrant toutes les ressources légitimes. Déployez-la en mode report-only et surveillez les violations indiquant que vous avez manqué une ressource.
Phase 3 : Affinage. Sur une à deux semaines, vérifiez quotidiennement les rapports de violations et ajoutez toutes les sources légitimes que vous avez manquées. Faites attention aux rapports provenant de types de pages ou de flux utilisateurs spécifiques que vous n'avez peut-être pas testés manuellement.
Phase 4 : Application. Passez de Content-Security-Policy-Report-Only à Content-Security-Policy. Gardez la directive report-uri pour continuer à recevoir les rapports de violations. Surveillez attentivement la première semaine après l'application pour détecter les ressources légitimes qui sont bloquées.
Phase 5 : Renforcement. Une fois l'application stable, cherchez des opportunités de renforcer la politique. Pouvez-vous remplacer 'unsafe-inline' dans script-src par des nonces ? Pouvez-vous restreindre les domaines génériques à des sous-domaines spécifiques ? Pouvez-vous supprimer des sources qui ne sont plus utilisées ? Chaque étape de renforcement améliore votre posture de sécurité.
Maintenance de votre CSP
Une CSP n'est pas une configuration à configurer puis oublier. Chaque fois que vous installez un nouveau module, ajoutez un service tiers, changez de passerelle de paiement ou mettez à jour votre thème, vous devrez peut-être mettre à jour votre CSP pour inclure de nouvelles sources de ressources. Faites de la révision CSP une partie de votre processus d'installation et de mise à jour de modules.
Gardez votre report-uri active même après l'application pour recevoir des alertes sur les nouvelles violations. Une augmentation soudaine des rapports de violations pourrait indiquer qu'une mise à jour de module a introduit de nouvelles exigences de ressources, ou cela pourrait indiquer une tentative d'attaque XSS réelle que votre CSP bloque avec succès. Dans les deux cas, vous voulez en être informé.
Documentez votre CSP et la raison de chaque entrée. Au fil du temps, les politiques accumulent des entrées pour des services que vous n'utilisez plus. Des révisions périodiques pour supprimer les entrées inutiles maintiennent la politique propre et réduisent la surface d'attaque. Une CSP avec moins de sources autorisées est intrinsèquement plus sûre qu'une avec beaucoup.
Cette réponse vous a-t-elle été utile ?
Vous avez encore des questions ?
Can't find what you're looking for? Send us your question and we'll get back to you quickly.