Symptômes · 11 min · publié le 12 juin 2024 · mis à jour le 26 décembre 2024

Mon site envoie du spam : trouver la source en une après-midi

Le domaine part en spam : plaintes, quota mail, inbox qui n'arrive plus chez Gmail. Quatre canaux tiennent presque tous les dossiers — formulaire, `mail()` PHP, SMTP du CMS, cron. Les journaux d'hébergement parlent plus qu'un antivirus Outlook. On coupe avant de réchauffer.

Réponse directe

Formulaire, PHP mail(), compte SMTP du CMS, cron. Les journaux d'hébergement parlent plus qu'un antivirus de messagerie. Coupez avant de « réchauffer » le domaine.

site envoie spam wordpress spam emails spam depuis mon domaine

Une après-midi, quatre tiroirs

Vous n'allez pas « scanner tout Internet ». Vous allez classer l'envoi. Si vous tenez le journal, le classement tient en une après-midi. Sans journal, vous changez de plugin au hasard et le quota explose encore le soir.

Les quatre tiroirs : (1) un formulaire ou une notification Woo/Presta détournée ; (2) un PHP qui appelle `mail()` ; (3) une clé Brevo / SMTP encore valide dans le CMS ; (4) un cron système. Un cinquième — usurpation DNS — se voit parce que le journal local est vide.

Ne commencez pas par un outil de warmup ou par un nouveau domaine. Vous déplacez la réputation sale, ou vous payez pour chauffer un robinet encore ouvert. L'ordre est coupe, cause, calme, puis seulement délivrabilité.

Un antivirus d'entreprise qui met vos mails en quarantaine n'est pas un diagnostic. C'est un symptôme aval. Le diagnostic est le log d'envoi.

Demander le journal d'envoi tout de suite

Ticket hébergeur, phrase unique : « merci de nous fournir le journal d'envoi (Exim/Postfix/mail) des 72 h, avec script ou authentification si vous l'avez ». Pas « rouvrez le mail ». Sur o2switch, OVH mutualisé, LWS, ce journal existe ; il part parfois au bout de quelques jours. Demandez-le le jour J.

Ce que vous y cherchez : l'heure, le volume, le `cwd` ou le chemin du PHP, l'utilisateur SMTP. Un `cwd=/home/xxx/www` plus un fichier que vous ne connaissez pas, le dossier est déjà à moitié clos. Voir journal d'envoi.

Si l'hébergeur a déjà coupé `mail()`, gardez la référence d'abus. Elle date le pic. Elle sert aussi quand vous demanderez la réouverture : cause traitée, pas « on a installé Wordfence ».

Tiroir 1 : le formulaire et les notifications

Si le log aligne les envois sur des `POST /contact`, allez sur formulaire de contact. Destinataire, BCC, `From` dynamique, second shortcode. Les notifications de commande (Woo, Presta) sont le même tiroir : un e-mail « nouvelle commande » réécrit avec 50 destinataires.

Flamingo, les entrées WPForms, les threads PrestaShop : ils montrent le contenu. Un corps d'e-mail pharmacie dans une « demande de devis » est soit un bot, soit un champ qui relaye. Dans les deux cas, l'envoi part de chez vous.

Coupez ces notifications le temps du tri. Un client réel attendra une heure de plus ; une file de 10 000 mails, non.

Tiroir 2 : PHP `mail()` hors CMS

Le log cite un chemin : `radio.php`, `wp-tmp.php`, un fichier dans `uploads`, un `tmp` hors webroot. Copiez, notez la date, retirez. Ne le « nettoyez » pas à la main en laissant une ligne `eval`.

Si le chemin est un fichier cœur (`wp-login.php` trop lourd), comparez au zip WordPress de la même version. Remplacez le fichier par l'officiel après copie du sale. Réinstaller tout WordPress par-dessus laisse le mu-plugin.

Interdisez `mail()` au niveau hébergeur tant que vous n'avez pas fini, si le support le propose. Ça casse aussi les mails légitimes : prévenez l'équipe. C'est moins grave qu'une blacklist IP du voisinage mutualisé.

  • Chemin cité par le log → copie → retrait.
  • Comparaison zip pour les fichiers cœur.
  • Uploads : pas d'exécution PHP.
  • mu-plugins et cron dans la même passe.

Tiroir 3 : la clé SMTP du CMS

Le log montre une authentification SMTP réussie, pas `mail()`. La clé est dans WP Mail SMTP, un `.env`, `wp_options`, un module Presta. Révoquez-la chez Brevo / Mailgun / OVH, pas seulement dans l'admin. Une clé révoquée côté fournisseur ferme le robinet même si le PHP la garde.

Regardez les campagnes dans Brevo : si des listes et des envois que vous n'avez pas lancés apparaissent, le compte marketing est le canal. Changez ce mot de passe, 2FA, webhooks. Voir Brevo après hack.

Un SMTP d'agence partagé entre dix sites : le spam d'un voisin vous attribue parfois les bounces. Distinguez l'identité d'enveloppe. Si `From` est vous et que l'auth est le compte partagé, séparez les identifiants après incident.

Tiroir 4 : cron et processus CLI

Pas de hit web, envoi à heure fixe : crontab du compte, « Tâches planifiées » cPanel, cron Magento, WP-CLI appelé par le système. Listez tout. Un `* * * * * php /home/…/cache/a.php` n'apparaît pas dans l'admin WordPress.

Les processus : `ps` sur un VPS, ou le gestionnaire de processus du panel. Un `php` à 99 % CPU qui n'est pas votre front, tuez-le après avoir noté la ligne de commande — c'est le chemin. Voir processeur saturé si la facture ou le load colle.

WP-Cron seul (`?doing_wp_cron`) peut envoyer si un plugin pirate s'y accroche. Désactiver WP-Cron sans cron système propre laisse des tâches en suspens ; l'inverse (cron système sale) est pire. Lisez les deux.

Couper, puis identifier, pas l'inverse

Pendant que vous cherchez, l'envoi continue et brûle l'IP. Coupez `mail()`, révoquez la clé, stoppez les cron inconnus. Ensuite vous lisez. L'inverse — chercher deux heures avec la file qui tourne — est le motif des IP déjà chez Spamhaus le soir.

Une page de maintenance sur le formulaire suffit. Ne coupez pas tout le vhost sauf phishing. Le SEO et le checkout n'ont pas à payer le mail.

Changez le mot de passe panel en premier. Un attaquant qui vous voit couper `mail()` réécrit un cron dans la minute si le panel est encore le sien.

Restaurer une sauvegarde « pour arrêter le spam » replace souvent le script. Copiez d'abord l'état actuel.

Usurpation hors serveur : SPF et voisins

Journal local vide, plaintes nombreuses : quelqu'un envoie en usurpant le `From`. Lisez SPF (`+all` est une porte), DKIM, les rapports DMARC (`rua`). Voir DMARC forensic. Ce n'est plus un malware de site ; c'est du DNS et de la messagerie.

Voisin de mutualisé : l'IP est partagée, un autre compte spam, vous héritez de la réputation. L'hébergeur le voit. Demandez si l'abuse est votre uid ou l'IP. Les réponses divergent, le traitement aussi (déménager d'IP vs nettoyer votre uid).

Un site qui cite votre marque dans des spam tiers n'envoie pas depuis chez vous. Ne formatez pas le CMS pour ça. Voir site cité dans des spam.

Réchauffer seulement un domaine calme

Logs calmes 24 à 48 h, cause retirée, SPF raisonnable, un e-mail transactionnel de test (commande, reset) vers Gmail et Orange. Puis le reste. Un outil de warmup sur un domaine encore abusé est de l'argent jeté.

Les newsletters attendent. Les reset de mot de passe aussi, si vous pouvez les faire via un autre canal un jour ou deux. Expliquez à l'équipe pourquoi, pas « le mail est cassé ».

Safe Browsing 24 à 72 h est une autre horloge, pour le web. Ne les mélangez pas dans le ticket hébergeur. Vous pouvez créer un espace si les quatre tiroirs restent ouverts au bout de l'après-midi : un log suffit souvent à un technicien pour pointer le fichier.

  • Calme des logs avant tout volume.
  • Test Gmail + Orange, pas seulement votre Outlook.
  • Transactionnel avant marketing.
  • Pas de nouveau domaine « pour repartir ».

Questions fréquentes

Puis-je changer de nom de domaine pour l'e-mail seulement ?

+
Un sous-domaine neuf (`mail2.`) avec un SPF propre aide parfois après nettoyage. Un nouveau .fr « pour l'image » perd la confiance et n'arrête pas le script. Traitez la cause d'abord.

Wordfence n'a rien vu, donc ce n'est pas mon site ?

+
Wordfence ne lit pas la file Exim. Un one-liner `mail()` n'a pas de signature. Le journal tranche, pas le scan.

L'hébergeur demande de « réchauffer ». Je le fais ?

+
Seulement si leurs logs à eux sont calmes et que la cause est écrite. Réchauffer pendant l'abuse, c'est leur redonner un motif de suspension.

Combien de temps pour sortir de Spamhaus ?

+
Souvent jours, parfois plus, selon le listing (domaine vs IP). La demande de retrait se fait après arrêt réel. Relancer toutes les heures n'accélère pas. Distinct de Safe Browsing.

Un prestataire « délivrabilité » suffit-il ?

+
Il ne retire pas le PHP. Engagez-le après le calme, pour SPF/DKIM et le plan de reprise. Avant, vous payez un vernis.
À lire ensuite
Formulaire de contact et spam PHP mail() abuse Journal d'envoi Réchauffer un domaine Tâches cron inconnues Déclarer mon site