Technique

Auto-whitelist sortants : la feature manquante de tous les anti-spam

Si vous écrivez à Bob, le mail de retour de Bob ne devrait JAMAIS être bloqué. C'est évident. Et pourtant, presque aucun anti-spam ne l'implémente correctement. Voici pourquoi, et comment FrozenSpam le fait.

Publié le 22 mai 2026 par Emmanuel Daunizeau · 9 min de lecture

Le problème

Imaginez un fonctionnement standard d'anti-spam par défi-réponse :

  1. Bob écrit à Alice pour la première fois
  2. L'anti-spam d'Alice ne connaît pas Bob → quarantaine + défi
  3. Bob valide → Bob est whitelisté → tout va bien

Maintenant inversez le scénario :

  1. Alice écrit à Bob pour la première fois (devis, propale, prise de contact)
  2. Bob répond
  3. L'anti-spam d'Alice ne connaît toujours pas Bob → quarantaine + défi
  4. Bob, agacé, peut ignorer le défi ou penser qu'Alice « bloque » sa réponse

C'est un cas absurde. Alice a initié la conversation. Bob a strictement zéro raison d'être bloqué. Et pourtant, c'est ce que MailInBlack, Spamarrest, et plusieurs autres font.

Pourquoi personne ne le fait correctement

Trois raisons techniques :

1. L'anti-spam ne « voit » que le flux entrant

La plupart des anti-spam sont des gateways MX : ils interceptent le mail qui arrive. Le mail qui part de chez Alice transite par son MTA local et part directement sur Internet, sans passer par la gateway anti-spam. Donc l'anti-spam ne sait pas qu'Alice a écrit à Bob.

2. Implémentation complexe

Pour savoir qu'Alice a écrit à Bob, il faut hooker le flux sortant du serveur mail d'Alice. Trois options :

  • Relay sortant via l'anti-spam — Alice envoie via la gateway aussi (pas seulement reçoit). Implique une configuration utilisateur plus complexe.
  • Webhook côté MTA — Le MTA d'Alice notifie l'anti-spam à chaque envoi. Implémenté via Postfix `sender_bcc_maps` ou Exchange transport rules. Demande de la coopération.
  • Poll IMAP sur le dossier Envoyés — L'anti-spam relit périodiquement le dossier « Envoyés » d'Alice. Peu invasif mais latence et permissions.

Aucune des trois options n'est triviale. C'est probablement pour ça que MailInBlack et compagnie ne l'ont pas implémenté.

3. Effet « apprentissage statistique »

Certains anti-spam (SaneBox notamment) prétendent faire de l'auto-WL sortants par apprentissage. C'est faux. Ils observent que vous interagissez avec un sender (lecture, réponse) et baissent son score spam. Mais c'est post-hoc : ça nécessite plusieurs allers-retours pour que le système « apprenne ». Et ça ne couvre pas le cas « première initiation ».

Comment FrozenSpam le fait

FrozenSpam V0 utilise une approche hybride :

  1. Pour les utilisateurs SmarterMail / Exchange on-premise : delivery hook côté MTA qui notifie l'engine FrozenSpam à chaque envoi sortant. Hook éprouvé sur 12 ans de production.
  2. Pour les utilisateurs OVH/Gandi/M365 : poll IMAP sur le dossier Envoyés toutes les 5 minutes, avec credentials chiffrés stockés en PG.
  3. Pour les utilisateurs Gmail Workspace : OAuth Gmail API qui lit le dossier `Sent` (lecture seule).

Tous les destinataires sortants des 90 derniers jours sont stockés dans la table outbound_log. Avant d'envoyer un défi, l'engine vérifie cette table. Si match → pass immédiat.

Le code (extrait simplifié)

def should_challenge(envelope_sender: str, tenant_id: int) -> bool:
    # Couches 1-3 dejà passées (DNSBL, SPF/DKIM/DMARC, AV)

    # Whitelist explicite ?
    if is_in_whitelist(envelope_sender, tenant_id):
        return False

    # Auto-WL sortants : ai-je écrit a ce sender dans les 90 derniers jours ?
    if is_in_outbound_log(envelope_sender, tenant_id, days=90):
        return False  # Pass immediat, AUCUN défi envoyé

    # Backscatter guard : SPF/DMARC du sender OK ?
    if spf_or_dmarc_failed(envelope_sender):
        return False  # Drop silencieux, pas de défi non plus

    # Sinon : challenge
    return True

Pourquoi c'est la garantie technique du zéro faux positif

Avec ce mécanisme, il n'existe AUCUN scénario où un humain qui essaye de vous joindre n'arrive pas à le faire :

  • Sender connu (whitelist explicite) → pass
  • Sender à qui j'ai écrit (outbound_log) → pass
  • Sender nouveau et authentifié → défi, validé en 10 sec → pass
  • Sender nouveau et usurpé (SPF/DMARC fail) → drop silencieux (mais ce n'est pas un faux positif puisque ce n'est pas l'humain réel qui écrit)

C'est par construction logique qu'il n'y a pas de faux positif. Pas par algorithme probabiliste, pas par chance. C'est démontrable.


FrozenSpam est aujourd'hui le seul anti-spam à exposer contractuellement cette garantie. Démarrez pour 1 €, remboursable sous 15 jours.