Les 37 contrôles que nous vérifions
La plupart des outils de sécurité affichent une note sans dire comment elle est obtenue. Voici l’inverse : chaque contrôle de notre moteur est documenté ci-dessous — ce qu’il observe, comment, quelle sévérité il retient, et ce qu’il ne prouve pas. La formule du score est publiée en clair.
37 contrôles + 6 états de scan · 43 constats possibles · 6 dimensions
Aucun de ces contrôles n’envoie de charge, ne teste d’identifiants, ni ne tente d’exploitation. Nous observons uniquement ce qui est publiquement exposé. Le nombre de constats réellement émis sur un domaine donné est inférieur à 43 : certains contrôles s’excluent mutuellement (un port propre remplace les constats par port, par exemple).
La formule du score
Chaque constat non conforme retire des points à sa dimension, selon sa sévérité. Le score de la dimension part de 100. Le score global est la moyenne des six dimensions, pondérée par leur poids. Aucune correction manuelle, aucun arrondi favorable, aucune intelligence artificielle : le même domaine dans le même état donne toujours le même score.
Pénalité par sévérité
- critical−45 pts
- high−25 pts
- medium−12 pts
- low−5 pts
- info−0 pts
Poids par dimension
- dns10 / 100
- https22 / 100
- headers14 / 100
- email20 / 100
- ports18 / 100
- exposure16 / 100
HTTPS & TLS
La sécurité de la connexion entre vos visiteurs et votre site. · 6 contrôles · poids 22/100
Disponibilité HTTPS
https-available
Le site répond-il en HTTPS sur le port 443 ?
- Comment c’est observé
- Requête GET https:// sur le port 443 de l'IP publique épinglée au début du scan, chemin « / », avec SNI et en-tête Host positionnés sur le nom de domaine et l'User-Agent « MonRempart-Intelligence/1.0 ». La vérification du certificat est volontairement désactivée pour cette sonde (rejectUnauthorized: false) afin d'observer la réponse même quand le certificat est invalide — sa validité est jugée par un contrôle distinct. Au plus 8 192 octets de corps sont lus, délai maximal 7 s. Aucune donnée applicative, aucun paramètre, aucun cookie, aucun identifiant n'est envoyé.
- Sévérité retenue
- Deux branches. Une réponse HTTPS est obtenue (quel que soit son code de statut : 200, 301, 403, 500…) → Info, conforme, 0 point de pénalité. Aucune réponse (erreur réseau, connexion refusée, ou délai de 7 s dépassé) → Critique, non conforme, 45 points de pénalité sur les 100 de la dimension HTTPS.
- Effort de correction
- Plus long (changement d’infrastructure)
Ce que ce contrôle ne prouve pas : Une réponse en HTTPS ne prouve pas que la connexion est sûre : la vérification du certificat étant désactivée pour cette sonde, un certificat expiré, auto-signé ou émis pour un autre nom donne quand même « HTTPS disponible ». Le constat ne porte que sur la racine « / » de l'IP épinglée, à un instant donné : derrière un répartiteur de charge ou un CDN, un autre nœud peut se comporter différemment.
Contrôle socle. Il est vérifié par le contenu de la réponse du serveur, pas par une supposition : le rendre masquable n’ouvrirait aucun usage légitime, seulement la possibilité de se mentir à soi-même.
Sévérité maximale : Critique. Source : https.
Certificat TLS
tls-cert
Le certificat TLS présenté est-il lisible, non expiré et rattaché à une chaîne de confiance ?
- Comment c’est observé
- Poignée de main TLS sur le port 443 de l'IP publique épinglée, SNI = domaine, vérification désactivée (rejectUnauthorized: false) afin de pouvoir lire un certificat même invalide. Le scanner lit trois éléments du certificat présenté : la date de fin de validité (champ valid_to), l'émetteur (organisation, à défaut nom commun) et l'indicateur socket.authorized calculé par Node (chaîne rattachée à une racine de confiance et nom concordant). La connexion est fermée aussitôt : aucune requête HTTP n'est émise, aucune donnée applicative ne circule. Délai maximal 7 s.
- Sévérité retenue
- Quatre branches. Certificat lu : jours restants = plancher((date d'expiration − maintenant) / 86 400 000). ≤ 0 jour (expiré) → Critique (45 points) · de 1 à 21 jours → Élevé (25 points) · au-delà de 21 jours → Info (0 point). Aucun certificat lisible (erreur, délai de 7 s dépassé, ou champ valid_to absent) → Élevé (25 points). Nuance de scoring à connaître : dans la branche Info, le constat n'est marqué « conforme » que si la chaîne est aussi validée (socket.authorized) ; une chaîne non validée laisse donc la sévérité à Info — 0 point de pénalité, aucun impact sur le score — tout en étant comptée comme constat non conforme dans le nombre de problèmes. Cas dégénéré : un champ valid_to présent mais illisible rend le calcul des jours restants indéterminé, ce qui retombe dans la branche Info (0 point).
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ce contrôle ne dit rien de la révocation du certificat (aucune vérification OCSP ni CRL), ni de la solidité de la clé ou de l'algorithme de signature. « Valide » signifie ici : non expiré au moment du scan, et — pour le statut conforme — rattaché à une racine de confiance ; sur le seul certificat présenté par l'IP épinglée, un autre nœud derrière le même nom pouvant en présenter un différent. Le seuil d'alerte (21 jours) est un choix éditorial, pas une norme.
Contrôle socle. Il est vérifié par le contenu de la réponse du serveur, pas par une supposition : le rendre masquable n’ouvrirait aucun usage légitime, seulement la possibilité de se mentir à soi-même.
Sévérité maximale : Critique. Source : node:tls.
Redirection HTTP → HTTPS
http-redirect
Le trafic en clair sur le port 80 est-il redirigé vers HTTPS — ou le port est-il simplement fermé ?
- Comment c’est observé
- Requête GET http:// en clair sur le port 80 de l'IP publique épinglée, chemin « / », en-tête Host = domaine, User-Agent « MonRempart-Intelligence/1.0 ». Seuls le code de statut et l'en-tête Location sont lus, puis la réponse est détruite sans que le corps soit récupéré. Délai maximal 6 s. Aucune donnée applicative n'est envoyée.
- Sévérité retenue
- Trois états. Aucune réponse sur le port 80 (connexion refusée, erreur, ou délai de 6 s dépassé) → Info, conforme, 0 point : le constat publié est « port 80 fermé, aucune redirection nécessaire » et non « site accessible en clair ». Réponse avec un code 300 à 399 ET un en-tête Location commençant par « https:// » → Info, conforme, 0 point. Toute autre réponse — code 2xx, 4xx, 5xx, ou redirection dont la Location ne commence pas par « https:// » → Moyen, non conforme, 12 points de pénalité.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Une redirection vers https:// ne protège pas la première requête : celle-ci part en clair et reste interceptable — seul HSTS (contrôlé dans la dimension En-têtes) supprime ce premier aller-retour. Le test ne porte que sur la racine « / » : d'autres chemins peuvent ne pas rediriger. La destination n'est vérifiée qu'au préfixe « https:// » : une redirection vers un tout autre domaine est comptée conforme. Enfin, un port 80 muet au moment du scan ne prouve pas qu'il est fermé en permanence — un filtrage temporaire, ou visant notre adresse, donne le même résultat.
Sévérité maximale : Moyenne. Source : node:http.
Protocole TLS 1.0
tls-old-protocol
Le serveur accepte-t-il encore une négociation en TLS 1.0 ?
- Comment c’est observé
- Poignée de main TLS forcée sur le port 443 de l'IP épinglée, avec version minimale = version maximale = « TLSv1 », SNI = domaine, vérification du certificat désactivée, et liste de ciphers « DEFAULT@SECLEVEL=0 ». Ce niveau de sécurité OpenSSL abaissé est indispensable CÔTÉ CLIENT : les versions récentes de Node refusent elles-mêmes TLS 1.0, et sans ce paramètre la sonde échouerait systématiquement, produisant un faux négatif. Le serveur est réputé accepter TLS 1.0 si et seulement si la poignée de main aboutit. Une seconde sonde identique en « TLSv1.1 » est lancée : elle nuance le texte de ce constat et, si TLS 1.0 est refusé alors que TLS 1.1 est accepté, déclenche le constat distinct « tls-old-protocol-11 ». Délai 6 s. Aucune requête HTTP, aucune donnée applicative n'est envoyée.
- Sévérité retenue
- Deux branches de sévérité. Poignée de main TLS 1.0 acceptée → Élevé (25 points), non conforme. Refusée → Info (0 point), conforme. Le texte du constat se décline en trois variantes (TLS 1.0 accepté / TLS 1.1 accepté mais 1.0 refusé / les deux refusés) mais la sévérité ne dépend que du résultat TLS 1.0 : l'acceptation de TLS 1.1 seule est portée par le constat distinct tls-old-protocol-11.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Accepter TLS 1.0 ne signifie pas que vos visiteurs l'utilisent : les navigateurs modernes le refusent d'eux-mêmes. Inversement, un refus constaté ne prouve pas que le serveur est configuré pour refuser TLS 1.0 : un équipement intermédiaire (pare-feu, WAF, protection anti-DDoS) peut avoir coupé notre poignée de main. Et un protocole obsolète accepté n'est pas la preuve d'une interception : c'est une possibilité laissée ouverte, pas un incident.
Sévérité maximale : Élevée. Source : node:tls.
Protocole TLS 1.1
tls-old-protocol-11
Le serveur accepte-t-il encore une négociation en TLS 1.1 (alors qu'il refuse déjà TLS 1.0) ?
- Comment c’est observé
- Même méthode que pour TLS 1.0 : poignée de main forcée sur le port 443 de l'IP épinglée avec version minimale = version maximale = « TLSv1.1 », SNI = domaine, ciphers « DEFAULT@SECLEVEL=0 » (abaissement nécessaire côté client, Node refusant TLS 1.1 par défaut), vérification du certificat désactivée, délai 6 s. Acceptation = poignée de main aboutie. Aucune donnée applicative n'est envoyée.
- Sévérité retenue
- Une seule branche. Ce constat n'est émis QUE dans le cas « TLS 1.0 refusé ET TLS 1.1 accepté », et il vaut alors toujours Moyen (12 points), non conforme. Il n'existe pas de variante conforme : ce constat n'apparaît jamais pour dire que TLS 1.1 est refusé.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : L'absence de ce constat ne prouve pas que TLS 1.1 est refusé : il n'est tout simplement pas émis lorsque TLS 1.0 est déjà accepté — le problème est alors signalé, plus sévèrement, par le constat TLS 1.0. Comme pour ce dernier, un échec de poignée de main peut venir d'un équipement intermédiaire plutôt que de la configuration du serveur.
Sévérité maximale : Moyenne. Source : node:tls.
Suites cryptographiques faibles
tls-weak-cipher
Le serveur accepte-t-il de négocier avec une suite cryptographique faible (RC4 / 3DES / NULL) ?
- Comment c’est observé
- Poignée de main TLS sur le port 443 de l'IP épinglée en ne proposant que six suites réputées faibles — RC4-SHA, RC4-MD5, DES-CBC3-SHA, EXP-RC4-MD5, NULL-MD5, NULL-SHA — suffixées « @SECLEVEL=0 » (sans quoi le client Node refuserait lui-même ces suites), versions autorisées de TLS 1.0 à TLS 1.2, SNI = domaine, vérification du certificat désactivée, délai 6 s. Si la poignée de main aboutit, le nom de la suite négociée est repris tel quel ; si le module TLS ne l'expose pas, c'est le nom du protocole négocié qui est affiché, et à défaut la mention « inconnu ». Aucune requête HTTP, aucune donnée applicative n'est envoyée.
- Sévérité retenue
- Deux branches. Au moins une des six suites testées a été négociée → Élevé (25 points), non conforme. Toutes refusées (ou poignée de main échouée / délai dépassé) → Info (0 point), conforme.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : « Aucun cipher faible détecté » signifie exactement : ces six suites-là ont été refusées. D'autres suites faibles ou vieillissantes (export Diffie-Hellman, CBC-SHA1, autres variantes 3DES) ne sont pas testées, et la sonde n'explore que TLS 1.0 à TLS 1.2 — la configuration TLS 1.3 n'est pas évaluée. Ce contrôle n'est donc pas un audit cryptographique complet. À l'inverse, un échec de négociation peut venir d'un équipement intermédiaire et non du serveur lui-même.
Sévérité maximale : Élevée. Source : node:tls.
Authentification e-mail
Ce qui empêche qu’on envoie des e-mails en votre nom. · 3 contrôles · poids 20/100
Enregistrement SPF
email-spf
Le domaine publie-t-il un enregistrement SPF, et celui-ci rejette-t-il réellement les expéditeurs non autorisés ?
- Comment c’est observé
- Requête DNS TXT sur le domaine lui-même (dns.resolveTxt, résolveur système, délai maximum 5 s). Les fragments de chaque enregistrement TXT sont concaténés sans séparateur, puis on retient le PREMIER enregistrement dont le texte commence par « v=spf1 ». Sur cet enregistrement, on cherche le mécanisme « all » avec l'expression (?:^|\s)([-+~?]?)all(?:\s|$) : le qualificateur « + » (explicite ou implicite, car le qualificateur par défaut est Pass) et « ? » sont jugés permissifs ; « ~ » (SoftFail) et « - » (HardFail) sont jugés légitimes. Si aucun mécanisme « all » n'est trouvé, l'enregistrement est jugé permissif SAUF s'il contient une délégation « redirect= ». L'enregistrement complet est conservé tel quel dans rawSpf (le champ « detail » l'affiche tronqué à 120 caractères). Aucun email n'est envoyé, aucun serveur de messagerie n'est contacté.
- Sévérité retenue
- Trois branches exactement. Aucun enregistrement « v=spf1 » trouvé → Élevé (échec, −25 pts sur les 100 de la dimension) · SPF présent mais permissif, c'est-à-dire « +all », « all » sans qualificateur, « ?all », ou bien ni mécanisme « all » ni « redirect= » → Élevé (échec, −25 pts) · SPF présent contenant « ~all » ou « -all », ou contenant « redirect= » sans « all » → Info (réussite, 0 point).
- Effort de correction
- Modéré (à planifier avec votre prestataire)
Ce que ce contrôle ne prouve pas : Ne prouve pas que le SPF est correct dans le détail : les mécanismes « include: » ne sont pas déroulés — ni un include cassé, ni le dépassement de la limite RFC 7208 de 10 résolutions DNS (qui invalide tout le SPF) ne sont détectés. Si plusieurs enregistrements « v=spf1 » coexistent sur le domaine — ce qui rend le SPF invalide selon la RFC — seul le premier rencontré est lu, et le second n'est pas signalé. Ne prouve rien sur l'adresse « De : » que voit le destinataire : SPF n'authentifie que l'enveloppe (MAIL FROM). Enfin, une résolution DNS en échec ou en dépassement de délai renvoie une liste vide, indiscernable d'une vraie absence : le verdict « SPF absent » peut refléter un incident de résolution au moment du scan.
Sévérité maximale : Élevée. Source : node:dns.
Politique DMARC
email-dmarc
Une politique DMARC est-elle publiée, et est-elle appliquée (quarantaine / rejet) ou seulement en mode observation ?
- Comment c’est observé
- Requête DNS TXT sur le sous-domaine _dmarc.<domaine> (dns.resolveTxt, délai maximum 5 s). Les fragments TXT sont concaténés, on retient le premier enregistrement commençant par « v=DMARC1 », puis on extrait la politique via dmarcPolicy(), dont l'expression est ANCRÉE sur une frontière de balise — début d'enregistrement ou « ; ». Cet ancrage est indispensable : sans lui, une balise « sp= » (politique des sous-domaines) serait lue comme un « p= » et un domaine sans politique propre serait déclaré protégé. L'enregistrement complet est conservé dans rawDmarc (le champ « detail » n'affiche que la politique extraite). Aucun rapport DMARC n'est collecté, aucun email n'est envoyé, aucun serveur de messagerie n'est contacté.
- Sévérité retenue
- Trois branches exactement. Aucun enregistrement « v=DMARC1 » sur _dmarc.<domaine> → Élevé (échec, −25 pts sur les 100 de la dimension) · Enregistrement présent avec « p=none », OU enregistrement présent dont aucune politique n'est reconnue par l'expression → Moyen (échec, −12 pts) · Enregistrement présent avec « p=quarantine » ou « p=reject » → Info (réussite, 0 point).
- Effort de correction
- Modéré (à planifier avec votre prestataire)
Ce que ce contrôle ne prouve pas : Ne prouve pas que la politique s'applique à l'ensemble du flux : le paramètre « pct= » n'est jamais lu, donc un « p=reject; pct=0 » (rejet appliqué à 0 % des messages, soit une politique sans effet) est compté comme une politique active et réussie. Les paramètres d'alignement « adkim= » / « aspf= » et la présence d'une adresse de rapport « rua= » ne sont pas évalués. La recherche vise exactement _dmarc.<domaine>, sans remontée vers le domaine organisationnel : analyser un sous-domaine déjà couvert par la politique de son domaine parent produira « DMARC absent ». Comme pour le SPF, une résolution DNS en échec renvoie une liste vide, indiscernable d'une vraie absence.
Sévérité maximale : Élevée. Source : node:dns.
Clé publique DKIM
email-dkim
Une clé publique DKIM est-elle publiée sur l'un des sélecteurs courants, et est-elle utilisable (non révoquée) ?
- Comment c’est observé
- Requêtes DNS TXT successives (non parallèles) sur <sélecteur>._domainkey.<domaine> pour huit sélecteurs courants, dans cet ordre : default, google, selector1, selector2, k1, dkim, mail, s1 — délai maximum 2,5 s par sélecteur. La boucle s'arrête dès qu'un sélecteur porte une clé jugée valide. Un enregistrement est classé « valide » s'il contient « p= » suivi d'au moins 20 caractères base64 (expression p=\s*[A-Za-z0-9+/]{20,}, seuil destiné à écarter un TXT quelconque contenant « p= ») ; il est classé « révoqué » s'il contient à la fois « v=DKIM1 » et un « p= » vide, c'est-à-dire suivi d'un « ; » ou de la fin de chaîne (clé révoquée au sens RFC 6376). Une clé valide trouvée sur un sélecteur prime sur une clé révoquée trouvée sur un autre. Aucun email n'est envoyé, aucune signature n'est calculée ni vérifiée.
- Sévérité retenue
- Trois branches exactement. Clé valide trouvée sur au moins un des huit sélecteurs → Info (réussite, 0 point) · Aucune clé valide mais au moins un sélecteur portant une clé révoquée (« v=DKIM1 » avec « p= » vide) → Moyen (échec, −12 pts sur les 100 de la dimension) · Aucun enregistrement exploitable sur les huit sélecteurs → Faible (échec, −5 pts).
- Effort de correction
- Modéré (à planifier avec votre prestataire)
Ce que ce contrôle ne prouve pas : Ne prouve pas l'absence de DKIM : le nom du sélecteur est libre et seuls huit sélecteurs courants sont interrogés — une clé publiée sous un autre nom (cas fréquent chez les fournisseurs de messagerie) reste invisible pour ce contrôle, ce que le texte du constat reconnaît explicitement. Inversement, trouver une clé ne prouve pas que les emails sortants sont effectivement signés, ni que la signature serait vérifiable par un destinataire : rien n'est signé ni vérifié cryptographiquement, seule la présence d'une chaîne base64 d'au moins 20 caractères est constatée. Ni la taille de la clé, ni l'algorithme, ni la cohérence globale de l'enregistrement ne sont contrôlés. Comme pour le SPF et le DMARC, une résolution DNS en échec ou en dépassement de délai renvoie une liste vide, indiscernable d'une vraie absence.
Sévérité maximale : Moyenne. Source : node:dns.
Ports exposés
Les points d’entrée réseau joignables depuis Internet. · 12 contrôles · poids 18/100
Telnet (port 23)
port-23
Le port 23 (Telnet) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 23 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si l'événement « connect » se déclenche, c'est-à-dire si la poignée de main TCP aboutit ; la socket est alors détruite immédiatement. Aucun identifiant, aucune charge utile, aucune commande Telnet n'est envoyée et aucune bannière n'est lue. Les douze ports de la table sont sondés en parallèle (Promise.all, l.733-735).
- Sévérité retenue
- Branche unique. Port ouvert → Critique (−45 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé (RST) ou filtré (paquets ignorés) → AUCUN constat n'est émis : la fiche n'apparaît pas du tout dans le rapport. Un constat port-23 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Le service est nommé d'après le numéro de port et non d'après une bannière : rien ne prouve que c'est bien Telnet qui écoute sur 23. Le scan ne teste ni identifiants, ni version, ni exploitabilité.
Sévérité maximale : Critique. Source : node:net.
FTP (port 21)
port-21
Le port 21 (FTP) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 21 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si l'événement « connect » se déclenche ; la socket est détruite aussitôt. Aucun identifiant, aucune commande FTP (USER/PASS), aucune charge utile n'est envoyée et aucune bannière n'est lue. Les douze ports de la table sont sondés en parallèle (l.733-735).
- Sévérité retenue
- Branche unique. Port ouvert → Élevé (−25 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-21 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Le service est déduit du numéro de port, jamais d'une bannière : rien ne prouve que c'est FTP. Le scan ne vérifie ni la présence d'un accès anonyme, ni l'usage de FTPS/chiffrement, ni les droits sur les fichiers servis.
Sévérité maximale : Élevée. Source : node:net.
SSH (port 22)
port-22
Le port 22 (SSH) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 22 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si la poignée de main TCP aboutit ; la socket est détruite aussitôt. Aucune négociation SSH, aucune clé, aucun identifiant n'est envoyé et la bannière du démon n'est pas lue. Les douze ports de la table sont sondés en parallèle (l.733-735).
- Sévérité retenue
- Branche unique. Port ouvert → Moyen (−12 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-22 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Un SSH joignable est la situation normale d'un serveur administré à distance. Le scan ne dit rien du mode d'authentification (clé publique ou mot de passe), de la désactivation du compte root, d'un éventuel fail2ban, ni de la version du démon — et ne prouve même pas que c'est SSH qui écoute sur 22.
Sévérité maximale : Moyenne. Source : node:net.
RDP (port 3389)
port-3389
Le port 3389 (Bureau à distance RDP) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 3389 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si l'événement « connect » se déclenche ; la socket est détruite aussitôt. Aucune négociation RDP, aucun identifiant, aucune charge utile n'est envoyée et aucune bannière n'est lue. Les douze ports de la table sont sondés en parallèle (l.733-735).
- Sévérité retenue
- Branche unique. Port ouvert → Critique (−45 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-3389 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Le service est déduit du numéro de port, pas d'une bannière : rien ne prouve que c'est RDP. Le scan ne teste ni la NLA (authentification au niveau réseau), ni la robustesse des mots de passe, ni la présence d'une passerelle RDP, ni l'exploitabilité.
Sévérité maximale : Critique. Source : node:net.
MySQL (port 3306)
port-3306
Le port 3306 (base de données MySQL/MariaDB) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 3306 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si la poignée de main TCP aboutit ; la socket est détruite aussitôt. Aucune requête SQL, aucun identifiant de connexion, aucune charge utile n'est envoyée et le paquet de bienvenue du serveur n'est pas lu.
- Sévérité retenue
- Branche unique. Port ouvert → Critique (−45 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-3306 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Ce constat ne prouve NI que la base est accessible sans mot de passe, NI qu'une donnée est lisible : aucune requête n'est envoyée et aucune tentative d'authentification n'est faite. Le service est déduit du numéro de port : un autre logiciel peut occuper le 3306.
Sévérité maximale : Critique. Source : node:net.
PostgreSQL (port 5432)
port-5432
Le port 5432 (base de données PostgreSQL) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 5432 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si l'événement « connect » se déclenche ; la socket est détruite aussitôt. Aucun message de démarrage PostgreSQL, aucune requête SQL, aucun identifiant n'est envoyé.
- Sévérité retenue
- Branche unique. Port ouvert → Critique (−45 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-5432 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Le constat ne prouve NI que la base accepte une connexion sans mot de passe, NI que des données sont lisibles : la configuration pg_hba.conf n'est pas testée et aucune requête n'est envoyée. Le service est déduit du numéro de port.
Sévérité maximale : Critique. Source : node:net.
Redis (port 6379)
port-6379
Le port 6379 (Redis) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 6379 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si la poignée de main TCP aboutit ; la socket est détruite aussitôt. Aucune commande Redis (PING, INFO, AUTH…) n'est envoyée et aucune réponse applicative n'est lue.
- Sévérité retenue
- Branche unique. Port ouvert → Critique (−45 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-6379 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Le constat ne prouve pas que l'instance est sans mot de passe (requirepass) ni qu'elle répond en mode protégé : aucune commande n'est envoyée, donc ni PING ni INFO ne sont testés. Le service est déduit du numéro de port.
Sévérité maximale : Critique. Source : node:net.
MongoDB (port 27017)
port-27017
Le port 27017 (MongoDB) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 27017 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si l'événement « connect » se déclenche ; la socket est détruite aussitôt. Aucune commande MongoDB (isMaster, listDatabases…) n'est envoyée et aucun document n'est lu.
- Sévérité retenue
- Branche unique. Port ouvert → Critique (−45 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-27017 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Le constat ne prouve NI que l'authentification est désactivée, NI qu'une collection est lisible : aucune commande n'est envoyée. Le service est déduit du numéro de port.
Sévérité maximale : Critique. Source : node:net.
Elasticsearch (port 9200)
port-9200
Le port 9200 (Elasticsearch) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 9200 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si la poignée de main TCP aboutit ; la socket est détruite aussitôt. Aucune requête HTTP n'est envoyée sur ce port : ni « GET / », ni « _cat/indices », ni lecture d'index.
- Sévérité retenue
- Branche unique. Port ouvert → Critique (−45 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-9200 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Le constat ne prouve NI que le cluster répond sans authentification, NI qu'un index est consultable : la sonde s'arrête à la couche TCP et n'émet aucune requête HTTP. Le service est déduit du numéro de port.
Sévérité maximale : Critique. Source : node:net.
Memcached (port 11211)
port-11211
Le port 11211 (Memcached) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 11211 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si l'événement « connect » se déclenche ; la socket est détruite aussitôt. Aucune commande Memcached (stats, get…) n'est envoyée et aucune donnée en cache n'est lue. Le pendant UDP du service (souvent en cause dans les attaques par amplification) n'est pas testé : la sonde est exclusivement TCP.
- Sévérité retenue
- Branche unique. Port ouvert → Critique (−45 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-11211 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Le constat ne prouve pas que le cache est lisible, ni que le service est utilisable en amplification DDoS : le port UDP 11211 n'est jamais sondé et aucune commande n'est envoyée. Le service est déduit du numéro de port.
Sévérité maximale : Critique. Source : node:net.
CouchDB (port 5984)
port-5984
Le port 5984 (CouchDB) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 5984 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si la poignée de main TCP aboutit ; la socket est détruite aussitôt. Aucune requête HTTP n'est envoyée sur ce port et aucun document n'est lu.
- Sévérité retenue
- Branche unique. Port ouvert → Élevé (−25 points sur les 100 de la dimension « ports », pénalités cumulables, plancher à 0). Port fermé ou filtré → aucun constat n'est émis. Un constat port-5984 présent vaut donc toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Le constat ne prouve NI l'absence d'administrateur configuré (mode « admin party »), NI qu'une base est lisible : aucune requête HTTP n'est émise. Le service est déduit du numéro de port.
Sévérité maximale : Élevée. Source : node:net.
SMTP (port 25)
port-25
Le port 25 (SMTP) accepte-t-il des connexions entrantes depuis Internet ?
- Comment c’est observé
- Ouverture d'une connexion TCP vers le port 25 de l'unique IP publique épinglée au début du scan (net.connect, délai d'attente 1 500 ms, l.242-252). Le port est déclaré ouvert si et seulement si l'événement « connect » se déclenche ; la socket est détruite aussitôt. Aucune commande SMTP (EHLO, MAIL FROM, RCPT TO) n'est envoyée, aucun email n'est émis et la bannière du serveur n'est pas lue. Le libellé du constat indique explicitement qu'un port 25 ouvert est normal pour un serveur de messagerie (l.750-755).
- Sévérité retenue
- Branche unique de sévérité. Port ouvert → Faible (−5 points sur les 100 de la dimension « ports »). Port fermé ou filtré → aucun constat n'est émis. Seuls le détail et la recommandation ont une branche particulière (test `p.port === 25`, l.750 et 753) : formulation « normal pour un serveur de messagerie » au lieu de la formulation générique. Un constat port-25 présent vaut toujours « ouvert », passed = false.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Un port ouvert n'est pas une faille en soi : un pare-feu, une authentification ou un filtrage par IP source peuvent déjà le protéger — à confirmer côté serveur. Un port 25 ouvert est attendu sur un serveur de messagerie et ne constitue pas en soi une anomalie. Le scan ne vérifie NI le relais ouvert (open relay), NI le support de STARTTLS, NI l'authentification exigée : aucune commande SMTP n'est envoyée. Le contrôle est par ailleurs indépendant des enregistrements MX du domaine (dimension « dns »).
Sévérité maximale : Faible. Source : node:net.
Fichiers & exposition
Les fichiers sensibles laissés accessibles par erreur. · 6 contrôles · poids 16/100
Fichier .env exposé
exposure-env
Le fichier /.env, qui contient habituellement les secrets de l'application, est-il servi publiquement à la racine du site ?
- Comment c’est observé
- Une seule requête GET en HTTPS vers « /.env », adressée à l'IP publique épinglée au début du scan (première IPv4 publique, à défaut IPv6), port 443, avec SNI et en-tête Host = le domaine et User-Agent « MonRempart-Intelligence/1.0 ». La validité du certificat n'est pas exigée pour cette requête (rejectUnauthorized: false) : seul le contenu servi est observé, la validité du certificat étant testée séparément dans la dimension HTTPS. Lecture de 4 096 octets maximum, délai 5 s. Le constat n'est émis que si le code HTTP vaut exactement 200 ET que le corps contient une ligne commençant par un nom de variable en majuscules suivi de « = » (/^[A-Z][A-Z0-9_]*\s*=/m) ET qu'il ne contient ni « <html » ni « <!doctype » (filtre anti-page-d'erreur). Aucune donnée applicative n'est envoyée, aucune authentification ni contournement n'est tenté ; seul un booléen est conservé — le contenu lu n'est ni stocké ni reproduit dans le rapport.
- Sévérité retenue
- Branche unique : le constat n'existe que s'il est détecté → Critique, échoué, −45 points sur la dimension « Fichiers & données exposés » (poids 16/100). Il n'existe aucune version « réussie » de ce contrôle : si aucune des cinq sondes ne détecte quoi que ce soit, c'est le marqueur exposure-clean qui est émis à la place.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne prouve pas que les secrets contenus dans ce fichier sont encore valides, ni qu'ils ont déjà été exploités : le scanner ne vérifie que la FORME du contenu (une ligne « CLÉ=… ») et n'en lit au plus que 4 096 octets. À l'inverse, l'absence de ce constat ne prouve pas qu'aucun fichier d'environnement n'est exposé : seul le chemin exact « /.env » à la racine est interrogé — ni /.env.local, ni /.env.bak, ni un sous-répertoire ne sont testés.
Contrôle socle. Il est vérifié par le contenu de la réponse du serveur, pas par une supposition : le rendre masquable n’ouvrirait aucun usage légitime, seulement la possibilité de se mentir à soi-même.
Sévérité maximale : Critique. Source : https.
Dépôt Git exposé (.git/HEAD)
exposure-git
Le dossier /.git/ du site est-il servi publiquement, son fichier HEAD étant lisible ?
- Comment c’est observé
- Une seule requête GET en HTTPS vers « /.git/HEAD » sur l'IP publique épinglée (port 443, SNI et Host = domaine, User-Agent « MonRempart-Intelligence/1.0 », certificat non exigé, 4 096 octets maximum, délai 5 s). Le constat n'est émis que si le code HTTP vaut exactement 200 ET que le corps, une fois débarrassé des espaces de début et de fin, commence par « ref: » suivi d'une espace (/^ref:\s/) — la signature d'un véritable fichier HEAD de dépôt Git. Une seule requête : aucun parcours du reste du dossier .git, aucun téléchargement d'objets.
- Sévérité retenue
- Branche unique : émis uniquement en cas de détection → Critique, échoué, −45 points sur la dimension. Sinon aucune entrée pour cet identifiant (marqueur exposure-clean si les cinq sondes restent muettes).
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne prouve pas que l'intégralité du code source est téléchargeable : seul /.git/HEAD a été lu. Reconstituer le dépôt suppose que les objets (/.git/objects/…, packfiles, index) soient eux aussi servis, ce que le scanner ne teste pas. Symétriquement, un dépôt peut être partiellement exposé sans que ce constat apparaisse (par exemple HEAD bloqué en 403 alors que d'autres chemins répondent).
Contrôle socle. Il est vérifié par le contenu de la réponse du serveur, pas par une supposition : le rendre masquable n’ouvrirait aucun usage légitime, seulement la possibilité de se mentir à soi-même.
Sévérité maximale : Critique. Source : https.
Configuration Git exposée (.git/config)
exposure-gitconfig
Le fichier de configuration /.git/config est-il lisible publiquement ?
- Comment c’est observé
- Une seule requête GET en HTTPS vers « /.git/config » sur l'IP publique épinglée (port 443, SNI et Host = domaine, certificat non exigé, 4 096 octets maximum, délai 5 s). Le constat n'est émis que si le code HTTP vaut exactement 200 ET que le corps contient la section « [core] » ET qu'il ne contient pas « <html » (insensible à la casse). Le corps n'est ni conservé ni affiché : seul le résultat du test l'est.
- Sévérité retenue
- Branche unique : Critique en cas de détection (échoué, −45 points sur la dimension). Aucune entrée sinon.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne prouve pas que l'historique du dépôt est récupérable : ce fichier ne contient que la configuration locale du dépôt (dont, souvent, l'URL du dépôt distant et parfois un identifiant). Par ailleurs, le filtre anti-faux-positif est ici plus faible que pour /.env : seule la chaîne « <html » est exclue, pas « <!doctype » — une page servie en 200 contenant « [core] » sans balise <html> serait comptée comme une fuite.
Contrôle socle. Il est vérifié par le contenu de la réponse du serveur, pas par une supposition : le rendre masquable n’ouvrirait aucun usage légitime, seulement la possibilité de se mentir à soi-même.
Sévérité maximale : Critique. Source : https.
phpinfo() exposé
exposure-phpinfo
Une page phpinfo() est-elle laissée accessible en production sur /phpinfo.php ?
- Comment c’est observé
- Une seule requête GET en HTTPS vers « /phpinfo.php » sur l'IP publique épinglée (port 443, SNI et Host = domaine, certificat non exigé, 4 096 octets maximum, délai 5 s). Le constat n'est émis que si le code HTTP vaut exactement 200 ET que le corps contient « phpinfo() » ou « <title>PHP » suivi d'une espace puis d'un chiffre (l'espace est obligatoire dans l'expression) (test insensible à la casse). Aucun paramètre n'est envoyé, le contenu de la page n'est pas conservé.
- Sévérité retenue
- Branche unique : Élevé en cas de détection (échoué, −25 points sur la dimension). Aucune entrée sinon.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne prouve pas qu'une faille est exploitable : phpinfo() divulgue la configuration du serveur (version de PHP, chemins absolus, modules chargés, parfois des variables d'environnement) — c'est une aide au ciblage, pas une vulnérabilité en soi. L'absence de ce constat ne couvre rien au-delà du chemin testé : une page équivalente nommée info.php, test.php ou placée dans un sous-répertoire n'est pas cherchée.
Contrôle socle. Il est vérifié par le contenu de la réponse du serveur, pas par une supposition : le rendre masquable n’ouvrirait aucun usage légitime, seulement la possibilité de se mentir à soi-même.
Sévérité maximale : Élevée. Source : https.
Apache server-status exposé
exposure-serverstatus
La page d'état d'Apache /server-status est-elle accessible publiquement ?
- Comment c’est observé
- Une seule requête GET en HTTPS vers « /server-status » sur l'IP publique épinglée (port 443, SNI et Host = domaine, certificat non exigé, 4 096 octets maximum, délai 5 s). Le constat n'est émis que si le code HTTP vaut exactement 200 ET que le corps contient la chaîne « Apache Server Status » (insensible à la casse). Le contenu lu n'est ni stocké ni restitué dans le rapport.
- Sévérité retenue
- Branche unique : Moyen en cas de détection (échoué, −12 points sur la dimension). Aucune entrée sinon.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne prouve pas qu'un accès au serveur est possible : cette page divulgue l'activité en cours (URL traitées, adresses IP de clients, charge, temps de fonctionnement) — précieux pour cartographier un site, mais sans droit d'écriture ni d'exécution. Ne couvre que le chemin exact /server-status : ni /server-info, ni l'équivalent nginx, ni un chemin d'état personnalisé ne sont testés.
Contrôle socle. Il est vérifié par le contenu de la réponse du serveur, pas par une supposition : le rendre masquable n’ouvrirait aucun usage légitime, seulement la possibilité de se mentir à soi-même.
Sévérité maximale : Moyenne. Source : https.
security.txt
exposure-securitytxt
Un point de contact sécurité est-il publié en /.well-known/security.txt ?
- Comment c’est observé
- Une requête GET en HTTPS vers « /.well-known/security.txt » sur l'IP publique épinglée (port 443, SNI et Host = domaine, certificat non exigé), lecture de 2 048 octets maximum, délai 4 s — sonde plus courte que celles des cinq fichiers sensibles, et exécutée après elles. Le fichier est considéré présent si le code HTTP vaut exactement 200 ET que le corps contient une ligne du type « Contact : » (/contact\s*:/i, insensible à la casse). Aucune vérification du contenu du contact, aucune tentative de le joindre. Ce contrôle n'est PAS exécuté si le site n'a pas répondu en HTTPS (cf. marqueur exposure-na).
- Sévérité retenue
- La sévérité inscrite dans le constat vaut Basse dans les deux cas — c'est le résultat (réussi / échoué) qui décide de la pénalité, puisque le barème n'applique de pénalité qu'aux constats échoués : absent → échoué → −5 points sur la dimension ; présent → réussi → 0 point. Aucune branche plus sévère n'existe pour ce contrôle.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Sa présence ne prouve ni que l'adresse de contact est joignable, ni qu'un processus de traitement des signalements existe derrière : le scanner vérifie seulement qu'une réponse 200 contient une ligne « Contact: ». Son absence n'est pas une exposition : c'est une bonne pratique manquante (RFC 9116), pas une faille — et elle n'est constatée que sur ce chemin unique.
Sévérité maximale : Faible. Source : https.
En-têtes de sécurité
Les directives qui durcissent le navigateur de vos visiteurs. · 6 contrôles · poids 14/100
HSTS (Strict-Transport-Security)
header-strict-transport-security
Le site impose-t-il au navigateur de n'utiliser que HTTPS pour les visites suivantes (HSTS présent et actif) ?
- Comment c’est observé
- Le scanner lit la clé « strict-transport-security » dans les en-têtes de l'unique réponse à un GET HTTPS sur « / », adressé au port 443 de l'IP publique épinglée (SNI et en-tête Host = domaine, User-Agent « MonRempart-Intelligence/1.0 », Accept: */*). La validité du certificat n'est pas exigée pour cette requête (rejectUnauthorized: false) et les redirections ne sont pas suivies : ce sont les en-têtes de la réponse de « / », telle quelle, qui sont lus. Les noms d'en-têtes sont mis en minuscules et les valeurs multiples concaténées par « , ». La valeur est ensuite confrontée à l'expression /max-age\s*=\s*(\d+)/i et le nombre capturé doit être strictement supérieur à 0. Aucune donnée applicative n'est envoyée, aucun paramètre ni formulaire.
- Sévérité retenue
- La sévérité émise est FIXE (« Élevé ») dans les trois cas : c'est le drapeau passed qui décide de la pénalité. En-tête absent, ou présent avec une valeur vide → échec, 25 points retirés sur 100 à la dimension. Présent mais sans « max-age » exploitable, ou « max-age=0 » → échec « présent mais neutralisé », 25 points. Présent avec max-age > 0 → réussite, 0 point retiré.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne prouve pas que HSTS est correctement dimensionné : « max-age=1 » passe le contrôle exactement comme « max-age=31536000 ». Ni « includeSubDomains » ni « preload » ne sont vérifiés. Le contrôle ne porte que sur la réponse de la racine « / » de l'hôte scanné : un autre chemin, un sous-domaine, ou la page d'arrivée d'une redirection peuvent se comporter différemment.
Sévérité maximale : Élevée. Source : https.
Content-Security-Policy (CSP)
header-content-security-policy
Le site publie-t-il une Content-Security-Policy non vide ?
- Comment c’est observé
- Le scanner lit la clé « content-security-policy » dans les en-têtes de l'unique réponse à un GET HTTPS sur « / » (port 443 de l'IP publique épinglée, SNI et Host = domaine, certificat non exigé valide, redirections non suivies). Le seul test appliqué à la valeur est v.trim().length > 0 : aucune directive n'est analysée, aucun jugement n'est porté sur le contenu de la politique. Aucune donnée applicative n'est envoyée.
- Sévérité retenue
- La sévérité émise est FIXE (« Moyen ») dans les trois cas ; c'est passed qui décide de la pénalité. En-tête absent, ou présent avec une valeur vide → échec, 12 points retirés sur 100 à la dimension. Présent mais composé uniquement d'espaces → échec « présent mais neutralisé », 12 points. Présent avec au moins un caractère non blanc → réussite, 0 point retiré.
- Effort de correction
- Modéré (à planifier avec votre prestataire)
Ce que ce contrôle ne prouve pas : Ne prouve rien de la qualité de la politique : « default-src * » ou une CSP truffée de « unsafe-inline » / « unsafe-eval » passent le contrôle au même titre qu'une politique stricte. L'en-tête « Content-Security-Policy-Report-Only » n'est pas lu : un site qui n'est qu'en mode rapport est compté comme absent. Le contrôle ne porte que sur la réponse de la racine « / ».
Sévérité maximale : Moyenne. Source : https.
X-Frame-Options
header-x-frame-options
Le site interdit-il d'être affiché dans une iframe d'un site tiers (anti-clickjacking) ?
- Comment c’est observé
- Le scanner lit la clé « x-frame-options » dans les en-têtes de l'unique réponse à un GET HTTPS sur « / » (port 443 de l'IP publique épinglée, SNI et Host = domaine, redirections non suivies). La valeur est détourée (trim) puis confrontée à /^(deny|sameorigin)$/i : elle doit valoir exactement « DENY » ou « SAMEORIGIN », la casse étant indifférente. Si le serveur émet l'en-tête plusieurs fois, les valeurs sont concaténées par « , » avant ce test. Aucune donnée applicative n'est envoyée.
- Sévérité retenue
- La sévérité émise est FIXE (« Moyen ») dans les trois cas ; c'est passed qui décide de la pénalité. En-tête absent, ou présent avec une valeur vide → échec, 12 points retirés sur 100 à la dimension. Présent avec toute autre valeur que « DENY » ou « SAMEORIGIN » — par exemple « ALLOWALL », « ALLOW-FROM https://… », ou l'en-tête émis deux fois et concaténé en « SAMEORIGIN, SAMEORIGIN » — → échec « présent mais neutralisé », 12 points. Valeur exactement « DENY » ou « SAMEORIGIN » (casse et espaces de bord indifférents) → réussite, 0 point retiré.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne prouve pas l'absence de protection anti-clickjacking : la directive CSP « frame-ancestors », qui remplace X-Frame-Options dans les navigateurs modernes, n'est pas prise en compte — un site protégé uniquement par elle est compté « absent ». À l'inverse, l'en-tête légitimement émis en double est concaténé et échoue au test. Le contrôle ne porte que sur la réponse de la racine « / ».
Sévérité maximale : Moyenne. Source : https.
X-Content-Type-Options
header-x-content-type-options
Le serveur interdit-il au navigateur de deviner le type MIME des fichiers servis (nosniff) ?
- Comment c’est observé
- Le scanner lit la clé « x-content-type-options » dans les en-têtes de l'unique réponse à un GET HTTPS sur « / » (port 443 de l'IP publique épinglée, SNI et Host = domaine, redirections non suivies), et applique /nosniff/i à la valeur — une simple recherche de sous-chaîne, sans égalité stricte ni détourage. Aucune donnée applicative n'est envoyée.
- Sévérité retenue
- La sévérité émise est FIXE (« Faible ») dans les trois cas ; c'est passed qui décide de la pénalité. En-tête absent, ou présent avec une valeur vide → échec, 5 points retirés sur 100 à la dimension. Présent sans aucune occurrence de « nosniff » → échec « présent mais neutralisé », 5 points. Valeur contenant « nosniff » à n'importe quelle position, casse indifférente → réussite, 0 point retiré.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : La vérification est une recherche de sous-chaîne : une valeur mal formée qui contient « nosniff » passe le contrôle. Surtout, le contrôle ne porte que sur la réponse de la racine « / » — les contenus réellement à risque de confusion de type MIME (téléversements d'utilisateurs, exports, fichiers statiques) sont servis sur d'autres chemins, qui ne sont pas testés.
Sévérité maximale : Faible. Source : https.
Referrer-Policy
header-referrer-policy
Le site déclare-t-il une politique de transmission du referrer aux sites tiers ?
- Comment c’est observé
- Le scanner lit la clé « referrer-policy » dans les en-têtes de l'unique réponse à un GET HTTPS sur « / » (port 443 de l'IP publique épinglée, SNI et Host = domaine, redirections non suivies). Le seul test appliqué est v.trim().length > 0 : la valeur n'est comparée à aucune liste de tokens valides. Aucune donnée applicative n'est envoyée.
- Sévérité retenue
- La sévérité émise est FIXE (« Faible ») dans les trois cas ; c'est passed qui décide de la pénalité. En-tête absent, ou présent avec une valeur vide → échec, 5 points retirés sur 100 à la dimension. Présent mais composé uniquement d'espaces → échec « présent mais neutralisé », 5 points. Toute valeur contenant au moins un caractère non blanc → réussite, 0 point retiré.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne vérifie ni la validité ni la prudence de la valeur : « unsafe-url », qui transmet l'URL complète (chemin et paramètres) à tous les sites tiers, passe le contrôle au même titre que « no-referrer ». Un token inconnu, que le navigateur ignorera au profit de son comportement par défaut, passe également. Le contrôle ne porte que sur la réponse de la racine « / ».
Sévérité maximale : Faible. Source : https.
Permissions-Policy
header-permissions-policy
Le site restreint-il l'accès des pages aux API sensibles du navigateur (caméra, micro, géolocalisation) ?
- Comment c’est observé
- Le scanner lit la clé « permissions-policy » dans les en-têtes de l'unique réponse à un GET HTTPS sur « / » (port 443 de l'IP publique épinglée, SNI et Host = domaine, redirections non suivies). Le seul test appliqué est v.trim().length > 0 : aucune directive n'est décodée, aucune API particulière n'est recherchée. Aucune donnée applicative n'est envoyée.
- Sévérité retenue
- La sévérité émise est FIXE (« Faible ») dans les trois cas ; c'est passed qui décide de la pénalité. En-tête absent, ou présent avec une valeur vide → échec, 5 points retirés sur 100 à la dimension. Présent mais composé uniquement d'espaces → échec « présent mais neutralisé », 5 points. Toute valeur contenant au moins un caractère non blanc → réussite, 0 point retiré.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Aucune directive n'étant analysée, une politique qui ne restreint rien — ou qui ne mentionne aucune des API sensibles — passe le contrôle. L'ancien en-tête « Feature-Policy » n'est pas lu : un site qui n'utilise que celui-ci est compté comme absent. Le contrôle ne porte que sur la réponse de la racine « / ».
Sévérité maximale : Faible. Source : https.
DNS & domaine
La couche qui relie votre nom de domaine à vos services. · 4 contrôles · poids 10/100
Résolution DNS
dns-resolve
Le domaine résout-il vers au moins une adresse IP ?
- Comment c’est observé
- Deux requêtes DNS via le résolveur système du serveur de scan : dns.resolve4 (enregistrements A) puis dns.resolve6 (enregistrements AAAA), chacune plafonnée à 5 secondes — au-delà, ou en cas d'erreur, la liste est traitée comme vide. Le contrôle est réussi dès qu'au moins une adresse est renvoyée, tous types confondus. Les quatre premières adresses sont reprises telles quelles dans le détail du constat. Le domaine saisi est d'abord normalisé : protocole, chemin, port et préfixe « www. » sont retirés. Aucune connexion n'est ouverte vers le domaine à cette étape : seul le résolveur est interrogé.
- Sévérité retenue
- Deux branches, sans intermédiaire. Au moins un enregistrement A ou AAAA → Info, contrôle réussi, 0 point retiré. Aucun A ni AAAA → Critique, contrôle échoué, −45 points sur le score de la dimension DNS (soit −4,5 points sur le score global, la dimension pesant 10 sur un total de poids de 100).
- Effort de correction
- Plus long (changement d’infrastructure)
Ce que ce contrôle ne prouve pas : Ne prouve pas que le site fonctionne : une adresse IP publiée n'implique ni serveur qui répond, ni service correct — c'est la dimension HTTPS/TLS qui le vérifie. Symétriquement, un « ne résout pas » n'est pas toujours une panne : le préfixe « www. » étant retiré du domaine saisi, un site publié uniquement sur www.exemple.fr sans enregistrement sur le domaine nu sera vu comme non résolu ; et une réponse DNS légitime mais plus lente que le plafond de 5 secondes est comptée comme absence d'enregistrement. Enfin le constat reflète une seule résolution, depuis un seul résolveur, à un instant donné : il ne dit rien de ce que voient d'autres résolveurs ni d'une propagation en cours.
Contrôle socle. Il est vérifié par le contenu de la réponse du serveur, pas par une supposition : le rendre masquable n’ouvrirait aucun usage légitime, seulement la possibilité de se mentir à soi-même.
Sévérité maximale : Critique. Source : node:dns.
Serveurs de messagerie (MX)
dns-mx
Le domaine publie-t-il des enregistrements MX (serveurs de messagerie) ?
- Comment c’est observé
- Une requête DNS de type MX sur le domaine (dns.resolveMx), plafonnée à 5 secondes — au-delà, ou en cas d'erreur, la liste est traitée comme vide. Seul le NOMBRE d'enregistrements renvoyés est retenu et affiché ; ni les noms d'hôtes ni les priorités ne sont publiés dans le constat. Aucune connexion n'est ouverte vers les serveurs de messagerie : ils ne sont ni contactés, ni testés.
- Sévérité retenue
- Sévérité unique : Info dans les deux branches. Au moins un MX → contrôle réussi. Aucun MX → contrôle marqué en échec, mais la pénalité associée à « Info » vaut 0 point : le score de la dimension DNS est identique dans les deux cas. Ce constat est purement informatif et ne pénalise jamais.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne prouve pas que la messagerie fonctionne, ni qu'elle est correctement configurée : la présence d'enregistrements MX est constatée dans le DNS, les serveurs désignés ne sont jamais joints. À l'inverse, l'absence de MX ne met pas le domaine à l'abri : un domaine sans MX peut parfaitement être usurpé comme expéditeur — c'est SPF, DKIM et DMARC qui encadrent cela, dans la dimension Authentification email. Ce constat sert à contextualiser cette dimension, pas à juger.
Sévérité maximale : Information. Source : node:dns.
Signature DNSSEC
dns-dnssec
La zone DNS est-elle signée, et sa signature est-elle validée par un résolveur validant ?
- Comment c’est observé
- Une requête DNS-over-HTTPS de type A vers cloudflare-dns.com/dns-query (résolveur public validant, en-tête Accept: application/dns-json, plafond 5 secondes, aucune clé d'API), puis lecture de deux champs de la réponse JSON : le drapeau AD (Authenticated Data) et le champ Status. AD à true = chaîne de signature validée. AD absent avec Status égal à 2 (SERVFAIL renvoyé par un résolveur validant) = signature présente mais incohérente, distincte d'une zone simplement non signée. Aucune connexion n'est ouverte vers le domaine analysé : c'est Cloudflare qui est interrogé, sur le nom du domaine.
- Sévérité retenue
- Trois branches réellement émises. AD=true (chaîne validée) → Faible, contrôle réussi, 0 point retiré. AD absent et Status=2 (signature présente mais validation en échec) → Moyen, échec, −12 points sur la dimension DNS. AD absent et Status différent de 2 (zone non signée) → Faible, échec, −5 points sur la dimension DNS. Quatrième cas, hors sévérité : si la requête DoH n'aboutit pas (erreur réseau, réponse HTTP non-OK, dépassement des 5 secondes), AUCUN constat n'est émis — le contrôle disparaît du rapport au lieu d'être compté en échec.
- Effort de correction
- Modéré (à planifier avec votre prestataire)
Ce que ce contrôle ne prouve pas : Ne prouve rien sur la sécurité du site lui-même : DNSSEC authentifie les réponses DNS, pas le serveur web ni son contenu. Le résultat dépend d'un tiers et d'un instant : un « non signé » peut refléter un incident ou une réponse dégradée côté résolveur Cloudflare plutôt que l'état réel de la zone. Une zone signée ne protège en outre l'internaute que si SON résolveur valide DNSSEC — beaucoup ne le font pas. Enfin, la sévérité reste basse hors cas d'échec de validation : l'absence de DNSSEC est une piste de durcissement, pas une exposition active.
Sévérité maximale : Moyenne. Source : doh.
Enregistrement CAA
dns-caa
Le domaine restreint-il les autorités de certification habilitées à lui délivrer un certificat ?
- Comment c’est observé
- Une requête DNS-over-HTTPS de type CAA vers cloudflare-dns.com/dns-query (plafond 5 secondes, aucune clé d'API). Cloudflare renvoyant ces enregistrements au format RDATA générique (« \# <longueur> <hexadécimal> »), le scanner les décode lui-même : conversion de l'hexadécimal en octets, lecture de l'octet de longueur du tag, extraction du tag en ASCII puis de la valeur. Les tags sont comparés en minuscules (insensibilité à la casse, RFC 8659). Seuls les tags « issue » et « issuewild » sont comptés comme autorités autorisées ; le tag « iodef », qui n'est qu'une adresse de signalement et n'autorise personne, est explicitement écarté. Le contrôle est réussi s'il reste au moins une autorité, dont la liste est affichée dans le détail. Aucune connexion n'est ouverte vers le domaine analysé.
- Sévérité retenue
- Sévérité unique : Faible. Au moins un tag issue ou issuewild décodé → contrôle réussi, 0 point retiré. Aucun tag issue/issuewild — y compris lorsque le domaine ne publie qu'un tag iodef, ou lorsqu'aucun RDATA n'a pu être décodé → Faible, échec, −5 points sur la dimension DNS. Cas hors sévérité : si la requête DoH n'aboutit pas (erreur réseau, réponse HTTP non-OK, dépassement des 5 secondes), AUCUN constat n'est émis — le contrôle disparaît du rapport au lieu d'être compté en échec.
- Effort de correction
- Rapide (quelques minutes)
Ce que ce contrôle ne prouve pas : Ne prouve pas qu'aucun certificat indésirable n'existe pour ce domaine : CAA est une consigne que les autorités de certification sont tenues de consulter au moment de l'émission, pas un blocage technique. Il n'invalide aucun certificat déjà émis et ne peut rien contre une autorité compromise ou qui l'ignorerait. Symétriquement, son absence n'indique aucune compromission : c'est une piste de durcissement, d'où la sévérité basse. Limite de méthode à connaître : le décodage suppose le format RDATA générique renvoyé par Cloudflare ; un enregistrement présenté sous une autre forme ne serait pas décodé et compterait comme absent.
Sévérité maximale : Faible. Source : doh.
États du scan
Ces 6 identifiants ne sont pas des contrôles : ils décrivent ce que le moteur a pu observer (ou non). Ils ne sont pas comptés dans les 37 contrôles.
HTTPS non analysable (domaine injoignable)
https-na
Le scan a-t-il seulement pu atteindre le domaine pour analyser HTTPS/TLS ?
- Comment c’est observé
- Aucune connexion n'est tentée. Ce marqueur est produit en amont, à partir de la seule résolution DNS : le scanner a interrogé les enregistrements A puis AAAA (délai de 5 s chacun) et n'a obtenu aucune adresse, donc aucune IP publique n'a pu être épinglée. Les six contrôles HTTPS/TLS sont alors remplacés par ce marqueur unique. Cas distinct du refus anti-SSRF : si le domaine résout uniquement vers des adresses privées, le scan est interrompu par une erreur et ne produit aucun résultat.
- Ce que cet état signifie
- Une seule branche : toujours Critique (45 points), toujours non conforme. Émis uniquement lorsque le domaine ne renvoie aucun enregistrement A/AAAA, auquel cas il constitue à lui seul l'intégralité de la dimension HTTPS (score de dimension : 55/100).
Ce que ce contrôle ne prouve pas : Ce marqueur décrit l'état du scan, pas la sécurité du site : aucune connexion n'ayant été tentée, il ne prouve ni l'absence de HTTPS, ni un défaut de configuration TLS. Une résolution DNS lente ou bloquée au-delà de 5 s produit exactement le même marqueur qu'un domaine réellement dépourvu d'enregistrement A/AAAA.
État du scan, pas un contrôle : il décrit ce que le moteur a pu observer. Il n’est ni masquable ni surchargeable.
Sévérité maximale : Critique. Source : node:dns.
Aucun port sensible exposé
ports-clean
Aucun des douze ports sensibles testés n'a-t-il accepté de connexion ?
- Comment c’est observé
- Les douze ports de la table SENSITIVE_PORTS (23, 21, 22, 3389, 3306, 5432, 6379, 27017, 9200, 11211, 5984, 25) sont sondés en parallèle par simple ouverture de connexion TCP sur l'IP publique épinglée, avec un délai d'attente de 1 500 ms chacun. Aucun identifiant, aucune charge utile, aucune commande applicative n'est envoyée. Ce marqueur est émis si et seulement si aucune des douze sondes n'a abouti (`open.length === 0`, l.738). Il remplace alors la totalité des constats de la dimension.
- Ce que cet état signifie
- Branche unique : Info, passed = true, 0 point de pénalité → dimension « ports » à 100/100, statut « ok ». Dès qu'un seul port répond, ce marqueur n'est PAS émis : il est remplacé par une fiche port-<numéro> pour chaque port ouvert (et seulement pour ceux-là).
Ce que ce contrôle ne prouve pas : Ce marqueur ne prouve pas que la machine n'expose rien : seuls 12 ports sur 65 535 sont testés, uniquement en TCP (aucune sonde UDP), uniquement sur l'IP publique épinglée au début du scan — les autres adresses A/AAAA du domaine, les sous-domaines et les autres serveurs de l'organisation ne sont pas balayés. La sonde ne distingue pas « fermé » de « filtré » : un port protégé par filtrage d'IP source peut être parfaitement ouvert pour d'autres réseaux, et un service lent ou volontairement ralenti peut dépasser les 1 500 ms et être compté fermé. Enfin, le résultat est un instantané à la date du scan.
État du scan, pas un contrôle : il décrit ce que le moteur a pu observer. Il n’est ni masquable ni surchargeable.
Sévérité maximale : Information. Source : node:net.
Ports : domaine injoignable
ports-na
La dimension « ports » a-t-elle pu être analysée ?
- Comment c’est observé
- Aucune sonde réseau n'est effectuée. Après résolution DNS du domaine (dns.resolve4 puis dns.resolve6, l.258-262), si aucune adresse IP n'est obtenue, aucune IP ne peut être épinglée (pickPinnedIp, l.149-154), `checkPorts` n'est jamais appelé et ce marqueur est substitué à l'ensemble de la dimension (l.881-888). Cas distinct du domaine qui résout vers une adresse exclusivement privée : celui-ci fait échouer le scan entier avec une ScanError avant toute connexion (l.858-860), donc aucun rapport n'est produit.
- Ce que cet état signifie
- Branche unique : Critique, passed = false, codée en dur dans la fabrique `na` (l.882) → −45 points, dimension « ports » à 55/100, statut « warn ». Aucune autre valeur n'est atteignable pour cet identifiant.
Ce que ce contrôle ne prouve pas : Ce marqueur ne dit rien de l'exposition réelle des ports : il signale que le contrôle n'a pas eu lieu, pas qu'il a échoué côté cible. La pénalité de 45 points reflète l'impossibilité d'analyser, pas un risque observé. Inversement, l'absence de fiches port-<numéro> dans un rapport portant ce marqueur ne signifie pas que les ports sont fermés — ils n'ont jamais été sondés.
État du scan, pas un contrôle : il décrit ce que le moteur a pu observer. Il n’est ni masquable ni surchargeable.
Sévérité maximale : Critique. Source : node:dns.
Aucun fichier sensible détecté
exposure-clean
Les cinq chemins sensibles testés sont-ils tous restés muets ?
- Comment c’est observé
- Marqueur d'état du scan, émis lorsque les cinq sondes de fichiers (/.env, /.git/HEAD, /.git/config, /phpinfo.php, /server-status), lancées en parallèle sur l'IP publique épinglée, n'ont produit AUCUNE détection — c'est-à-dire qu'aucune n'a renvoyé à la fois un code 200 et un contenu correspondant à sa signature. Il ne correspond à aucune requête supplémentaire : c'est la conclusion du même lot de cinq requêtes.
- Ce que cet état signifie
- Branche unique : Info, réussi, 0 point de pénalité (la sévérité « info » vaut 0 dans le barème). Dès qu'une seule sonde détecte quelque chose, ce marqueur disparaît et est remplacé par un constat par fuite détectée.
Ce que ce contrôle ne prouve pas : Ne prouve pas qu'aucun fichier sensible n'est exposé sur le site : seuls cinq chemins fixes sont testés, sans exploration ni indexation. Sauvegardes, exports SQL, archives, fichiers de configuration, interfaces d'administration ou simples variantes de nommage sous d'autres chemins ne sont pas couverts. La détection exige aussi un code exactement 200 : un fichier servi avec un autre code d'état échappe au test. Enfin, seuls les 4 096 premiers octets sont analysés — et si le serveur envoie un premier bloc plus gros que cette limite, le corps analysé est vide et la sonde ne peut rien détecter.
État du scan, pas un contrôle : il décrit ce que le moteur a pu observer. Il n’est ni masquable ni surchargeable.
Sévérité maximale : Information. Source : https.
Dimension non analysée
exposure-na
Pourquoi aucun contrôle de fichiers exposés n'a-t-il été exécuté ?
- Comment c’est observé
- Marqueur d'état du scan, émis sans aucune requête vers les chemins sensibles. Deux chemins de code distincts produisent le MÊME identifiant. (1) Variante « non applicable » : le domaine résout vers une IP publique, mais la requête HTTPS initiale sur « / » (port 443) n'a pas abouti ; la fonction d'analyse d'exposition sort immédiatement et ne lance ni les cinq sondes de fichiers ni la vérification de security.txt. (2) Variante « injoignable » : la résolution DNS (node:dns, resolve4 puis resolve6, chacune plafonnée à 5 s, tout échec ou dépassement étant ramené à une liste vide) n'a retourné aucune adresse, donc aucune IP n'a pu être épinglée ; toute la dimension est alors remplacée par un marqueur générique construit ligne 882 sous la forme « <dimension>-na ». À noter : si le domaine résout mais uniquement vers des adresses privées, le scan est refusé avant ce point (garde anti-SSRF) et aucun marqueur n'est produit.
- Ce que cet état signifie
- Deux branches contradictoires sous un même identifiant. (1) Site sans réponse HTTPS → Info, marqué RÉUSSI, 0 point de pénalité : la dimension « Fichiers & données exposés » affiche alors 100/100 alors qu'aucun fichier n'a été testé. (2) Domaine ne résolvant vers aucune adresse → Critique, marqué ÉCHOUÉ, −45 points : la dimension tombe à 55/100. Les libellés diffèrent également (« Analyse des fichiers exposés non applicable » contre « Fichiers exposés : domaine injoignable »).
Ce que ce contrôle ne prouve pas : Ne prouve rien sur l'état réel des fichiers du site : dans les deux variantes, aucun chemin sensible n'a été interrogé. Le score de la dimension traduit ici l'analysabilité, pas l'exposition — 100/100 dans la première variante ne signifie pas « rien n'est exposé », et 55/100 dans la seconde ne signifie pas « quelque chose est exposé ».
État du scan, pas un contrôle : il décrit ce que le moteur a pu observer. Il n’est ni masquable ni surchargeable.
Sévérité maximale : Critique. Source : node:dns.
Voir ces contrôles sur votre domaine
Le scan gratuit applique ces contrôles en quelques secondes et vous rend un score sur 100, sans inscription.
Scanner mon domaine gratuitementLes termes employés ici sont définis dans le glossaire.