Magecart et formjacking, comment détecter un skimmer côté client
CentralCSP Team ·
Dernière mise à jour:
Magecart est le nom d'une famille d'attaques qui volent les données de cartes de paiement et de formulaires en injectant du JavaScript malveillant dans une page de paiement. La technique s'appelle le formjacking : un skimmer lit ce qu'un client saisit dans le formulaire de paiement et en envoie discrètement une copie à l'attaquant, pendant que la transaction légitime aboutit toujours. Comme le skimmer s'exécute dans le navigateur, dans du code qui se charge de la même manière que vos vrais scripts, vos serveurs et votre pare-feu applicatif web ne le voient jamais. Le moyen de l'attraper est côté client : inventorier les scripts qui s'exécutent réellement, alerter quand cet ensemble change, et limiter ce qu'une injection peut faire avec une politique de sécurité du contenu (CSP) stricte.
C'est le pendant « menace » de comment les attaquants abusent de Google Tag Manager, qui couvre un vecteur de distribution courant, et de CSP pour PCI DSS v4, qui couvre les exigences de conformité bâties autour de ce risque précis.
Ce que sont Magecart et le formjacking
Un skimmer de formjacking est un petit bout de JavaScript qui s'attache au formulaire de paiement et capture les valeurs des champs : numéro de carte, expiration, CVV, nom, adresse. Il attend généralement un événement submit ou blur, lit les inputs, et les exfiltre vers un hôte contrôlé par l'attaquant, souvent déguisé en requête d'analytics ou d'image. Le client ne voit rien. La commande aboutit, le reçu arrive, et les données de la carte sont déjà parties.
Magecart est le terme générique pour les groupes de menace et les kits d'outils qui mènent ces attaques à grande échelle. Le nom vient des premières campagnes contre les boutiques Magento, mais la technique est indépendante de la plateforme. Tout site avec un formulaire de paiement ou de connexion est une cible, et le code du skimmer est souvent fortement obfusqué et change fréquemment pour échapper à la détection par signature.
Comment le skimmer arrive sur la page
L'injection passe rarement par votre propre code. Elle passe par quelque chose à quoi votre page fait déjà confiance.
- Un script tiers compromis. Un widget de chat, une balise d'analytics, un snippet de test A/B ou un SDK de paiement est chargé depuis un fournisseur. Si ce fournisseur est piraté, ou son CDN l'est, le fichier que vos clients récupèrent change, et il skimme désormais. Vous n'avez rien déployé ; le script que vous incluez déjà a fait le travail.
- Un CDN ou une dépendance trafiqués. Un script que vous hébergez sur un CDN, ou un paquet de votre build, est altéré en amont. L'URL est la même, l'intégrité non.
- Un tag manager détourné. Un outil dont le travail entier est d'injecter des scripts est un canal idéal. Un compte volé ou un éditeur aux permissions trop larges peut pousser un skimmer sur chaque page sans toucher à votre dépôt, le scénario couvert dans le risque de sécurité de Google Tag Manager.
- Une compromission côté serveur ou de la chaîne d'approvisionnement qui modifie directement le template de la page. Moins fréquent pour les cas à forte composante tierce, mais cela arrive.
Dans tous les cas, le code malveillant arrive de la même manière que le code légitime, ce qui est tout le problème pour la détection.
Pourquoi votre serveur ne le voit jamais
Un pare-feu applicatif web inspecte les requêtes et les réponses au niveau de votre origine. Un skimmer injecté via un script tiers ne passe pas du tout par votre origine : le navigateur le récupère directement auprès du fournisseur ou du CDN, l'exécute, et les données volées vont directement du navigateur à l'hôte de l'attaquant. Rien de ce trafic ne touche vos serveurs.
L'analyse du code source a le même angle mort. Votre dépôt et votre pipeline de build semblent propres, parce que le changement s'est produit dans une dépendance que vous chargez à l'exécution, pas dans du code que vous avez commité. La page telle que le navigateur du client l'assemble est différente de la page que votre CI a construite. C'est dans cet écart que vit le formjacking, et c'est pourquoi les deux exigences de PCI DSS v4 qui visent cette menace demandent des preuves issues du navigateur, pas du serveur.
Détectez-le côté client
Si le seul endroit où le skimmer est visible est le navigateur, c'est là que la détection doit s'exécuter. Trois contrôles fonctionnent ensemble : une référence de ce qui s'exécute, une alerte quand cette référence change, et une policy qui limite ce qu'une injection égarée peut faire.
Inventoriez chaque script qui s'exécute
Un inventaire de scripts est une liste structurée de chaque script que le navigateur charge et exécute réellement sur une page, propriétaire et tiers, construite à partir du reporting de hash CSP. CSP Level 3 permet au navigateur de calculer un hash de chaque script qu'il récupère et de le signaler, vous obtenez donc la vraie liste à partir de vrais chargements de page, pas une estimation issue de votre build. Avec la technologie, la version et les CVE connues rattachées, l'inventaire est votre référence de confiance : c'est l'ensemble des scripts qui ont leur place sur la page de paiement.
Alertez quand l'ensemble des scripts change
Une référence n'est utile que si vous êtes prévenu quand elle bouge. L'alerte de changement se déclenche quand les scripts d'une page sensible diffèrent de l'ensemble approuvé : une nouvelle origine, un nouveau bloc inline, un script qui n'était pas là hier, ou la même URL servant un hash différent. Sur une page de paiement, un script nouveau ou modifié est le premier signal d'un skimmer, la différence entre l'attraper en quelques heures et l'apprendre par un report de rétrofacturation des semaines plus tard. C'est la détection de changement et d'altération que l'exigence 11.6.1 de PCI DSS v4 demande aux pages de paiement d'exécuter.
Limitez l'injection avec une CSP stricte
La détection vous dit que quelque chose a changé ; une CSP stricte limite ce que ce changement peut faire en premier lieu. Plutôt que de faire confiance à une liste d'hôtes, une policy stricte fait confiance à un nonce par requête et utilise 'strict-dynamic' pour étendre cette confiance uniquement aux scripts que votre code de confiance charge. Un attaquant qui trouve un point d'injection ne peut pas exécuter de script, parce qu'il ne peut pas deviner le nonce, et une liste blanche d'hôtes dont il pourrait abuser est ignorée.
Content-Security-Policy:
script-src 'self' 'nonce-{SERVER-GENERATED-NONCE}' 'strict-dynamic';
connect-src 'self' https://api.your-psp.example;
object-src 'none';
base-uri 'none';
report-to csp-endpointReporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"Deux directives font un travail supplémentaire contre le formjacking. connect-src limite où la page peut envoyer des données, donc un skimmer qui essaie d'exfiltrer vers un hôte inconnu déclenche une violation au lieu d'un POST silencieux. base-uri 'none' bloque une injection de balise <base> qui pourrait rediriger chaque URL de script relative vers un attaquant. Les listes blanches d'hôtes sont aussi là où se cachent les contournements : une redirection ouverte ou un endpoint JSONP sur un hôte autorisé peut exécuter du code choisi par l'attaquant tout en satisfaisant une policy laxiste, ce qui est une autre raison de préférer un nonce à une liste d'hôtes. Construisez la policy avec l'approche Report-Only d'abord présentée dans comment construire une CSP solide, et vérifiez un brouillon avec le scanner CSP gratuit.
Comment CentralCSP s'intègre
CentralCSP ingère vos reports de violation et de hash CSP, construit l'inventaire de scripts pour chaque page, et alerte quand l'ensemble des scripts ou les headers de réponse changent. Un skimmer déployé via un fournisseur compromis ou une balise malveillante apparaît comme une alerte « nouveau script sur la page de paiement », avec l'origine et le hash, plutôt que comme une plainte client plus tard. Associez cela à la suite CSP pour appliquer une policy stricte, et vous avez les deux moitiés : limiter ce qu'une injection peut faire, et savoir au moment où elle apparaît.
Vous pouvez évaluer votre policy actuelle à la recherche de points faibles comme des listes blanches d'hôtes trop larges, puis démarrer un essai gratuit et pointer un header Report-Only de vos pages de paiement vers lui pour voir ce que ces pages chargent réellement avant d'appliquer.
Foire aux questions
Qu'est-ce que Magecart ?
Magecart est le nom des groupes de menace et des kits d'outils qui volent les données de cartes de paiement en injectant du JavaScript malveillant (un skimmer) dans les pages de paiement. La technique consistant à lire les champs de formulaire et à les exfiltrer s'appelle le formjacking. Le code arrive généralement via un script tiers, un CDN ou un tag manager compromis.
Comment détecter un skimmer de formjacking ?
Du côté du navigateur, parce que c'est le seul endroit où le skimmer est visible. Construisez un inventaire de scripts de chaque script qui s'exécute sur la page de paiement, alertez quand cet ensemble change (une nouvelle origine, un nouveau bloc inline, un hash modifié), et exécutez une CSP stricte pour qu'une injection ne puisse pas s'exécuter ni exfiltrer discrètement. Les logs serveur et les analyses de code source la ratent.
Pourquoi un pare-feu applicatif web rate-t-il Magecart ?
Un pare-feu inspecte le trafic au niveau de votre origine. Un skimmer chargé via un script tiers s'exécute dans le navigateur et envoie les données volées directement du navigateur à l'attaquant, sans jamais passer par vos serveurs. La page que le navigateur du client assemble diffère de celle que votre build a produite, et c'est dans cet écart que vit le skimmer.
Une CSP arrête-t-elle Magecart ?
Une CSP stricte qui fait confiance à un nonce et à 'strict-dynamic' plutôt qu'à des listes blanches d'hôtes empêche une injection sans rapport d'exécuter un script, et connect-src limite où les données peuvent être envoyées. Elle n'arrête pas un skimmer déployé via un script auquel vous faites délibérément confiance, c'est pourquoi la détection (inventaire plus alerte de changement) est l'autre moitié.
À retenir
Magecart et le formjacking volent les données de carte avec du JavaScript qui se charge exactement comme vos vrais scripts, donc le serveur ne le voit jamais. La détection doit venir du navigateur : un inventaire de scripts comme référence, une alerte de changement quand un script nouveau ou modifié apparaît sur une page de paiement, et une CSP stricte qui empêche une injection de s'exécuter ou d'exfiltrer en premier lieu. Ces contrôles transforment un changement invisible côté client en une alerte sur laquelle vous pouvez agir.
Pour aller plus loin : OWASP sur la sécurité côté client et des recherches d'éditeurs de sécurité sur le web skimming comme l'analyse d'Akamai des campagnes Magecart.
Sources
- Akamai, Magecart web-skimming research
- OWASP, Top 10 web application security risks
- W3C, Content Security Policy Level 3