API du vérificateur de lien
Une seule route, un seul verbe. Elle rend exactement la structure qu’affiche la page — il n’y a pas de « version API » du rapport, parce que deux descriptions du même résultat finissent toujours par diverger.
Appel
POST /api/verifier-lien
Content-Type: application/json
{ "url": "https://exemple.com/page" }L’adresse voyage dans le CORPS et non dans l’URL : elle contient souvent un jeton personnel (lien de réinitialisation, invitation, partage de fichier), et un paramètre d’URL finirait dans les journaux d’accès, l’historique du navigateur et l’en-tête Referer de la page suivante. La réponse est no-store pour la même raison.
Réponse — analyse aboutie
{
"ok": true,
"rapport": {
"version": 1,
"date": 1755172800000,
"url": { "saisie", "normalisee", "hote", "hoteUnicode", "domaine",
"sousDomaines", "tld", "port", "chemin", "requete", "estIp" },
"urlFinale": Constat<string>,
"redirections": Constat<Saut[]>,
"domaine": { "creeLe", "ageJours", "expireLe", "registrar", "statuts" },
"dns": { "a", "aaaa", "mx", "ns", "resout" },
"tls": { "valide", "emetteur", "sujet", "valideDu", "valideAu",
"joursRestants", "noms" },
"contenu": { "titre", "champMotDePasse", "formulaireExterne",
"typeContenu", "telechargement" },
"reputation": RapportReputation[],
"signaux": Signal[],
"verdict": { "indice", "niveau", "confiance", "plafonne",
"couverture", "resume" },
"sources": SourceUtilisee[],
"dureeMs": number
},
"consigne": "…",
"limites": [ "…" ],
"quotaRestant": 118
}L’enveloppe Constat<T>
Aucune valeur nue ne traverse ce module. Chaque champ des sections domaine, dns, tls et contenu est une enveloppe. Lisez `statut` AVANT `value` : afficher value sans regarder le statut est un bug, pas un raccourci.
{
"value": T | null,
"statut": "OBSERVE" | "CALCULE" | "DECLARE"
| "INDISPONIBLE" | "NON_CONFIGURE" | "ECHEC",
"source": "url" | "dns" | "rdap" | "tls" | "http" | "reputation" | "calcul" | "aucune",
"confiance": "haute" | "moyenne" | "faible",
"note": string, // obligatoire hors OBSERVE / CALCULE
"vuA": number | null
}DECLARE— la valeur vient du site lui-même et n’est pas vérifiée (titre de page, sujet d’un certificat gratuit).INDISPONIBLE— ne peut pas être obtenu ici. Ferme le sujet.NON_CONFIGURE— exige une clé absente de cette installation. Ouvre une action pour l’exploitant.ECHEC— tenté, sans succès. Ouvre une action pour l’appelant : réessayer.
Verdict
indice est un indice de CONFIANCE sur 100 : il monte vers le sûr, et il n’atteint jamais 0 ni 100. Il n’y a qu’une échelle — afficher tantôt « confiance 92 » et tantôt « risque 87 » mettrait deux échelles inversées dans la même interface.
| niveau | indice | libellé |
|---|---|---|
| faible | ≥ 78 | 🟢 Risque faible |
| prudence | ≥ 38 | 🟡 Prudence |
| eleve | ≥ 20 | 🟠 Risque élevé |
| critique | < 28 | 🔴 Danger |
plafonne: true signifie que la confiance a EMPÊCHÉ le verdict d’aller au bout de ce que l’indice suggérait. Le plafond joue dans les deux sens : à confiance faible, un lien ne peut être ni déclaré « risque faible », ni déclaré « danger ». Un client qui ignore ce champ affichera un verdict plus tranché que ce que l’analyse autorise.
Signaux
Le catalogue complet, avec son poids en points ajoutés à l’indice. Un seul signal est decisif : il exige une correspondance exacte de l’URL dans une base de menaces, et aucune heuristique n’y a accès.
| id | gravité | points |
|---|---|---|
| reputation_malveillant | decisif | -200 |
| reputation_suspect | serieux | -34 |
| marque_ressemblante | serieux | -32 |
| homoglyphe | serieux | -30 |
| telechargement_executable | serieux | -30 |
| marque_dans_sous_domaine | serieux | -28 |
| tls_nom_non_couvert | serieux | -28 |
| mot_de_passe_sans_reputation | serieux | -26 |
| tls_expire | serieux | -26 |
| tls_invalide | serieux | -24 |
| formulaire_externe | serieux | -22 |
| ip_directe | serieux | -22 |
| domaine_tres_recent | attention | -18 |
| redirection_change_domaine | attention | -14 |
| pas_de_https | attention | -14 |
| encodage_inhabituel | attention | -12 |
| sous_domaines_nombreux | attention | -12 |
| port_inhabituel | attention | -12 |
| redirections_multiples | attention | -12 |
| domaine_sans_serveur | attention | -10 |
| domaine_recent | info | -9 |
| url_tres_longue | info | -8 |
| tld_a_risque | info | -8 |
| mots_sensibles | info | -7 |
| marque_dans_chemin | info | -6 |
| raccourcisseur | info | -6 |
| heberge_sous_domaine_ouvert | info | -6 |
| parametres_suspects | info | -6 |
| domaine_tres_connu | rassurant | +26 |
| domaine_etabli | rassurant | +22 |
| reputation_propre | rassurant | +18 |
| domaine_ancien | rassurant | +14 |
| https_certificat_valide | rassurant | +12 |
| certificat_organisation | rassurant | +8 |
| infrastructure_complete | rassurant | +6 |
| aucune_redirection | rassurant | +5 |
Ces poids ne sont pas des probabilités mesurées : il n’existe pas ici de corpus de liens étiquetés. Ce sont des jugements d’ingénierie, réunis dans un seul objet (SCORING_POLICY) pour qu’ils puissent être balayés le jour où un corpus existera. L’indice de base est 58 — un lien dont on ne sait rien reste au milieu, et le milieu s’appelle « prudence ».
Sources de réputation
Google Safe Browsing
Base de menaces qui alimente les avertissements de Chrome, Firefox et Safari.
variable : GOOGLE_SAFE_BROWSING_KEY · configurée sur cette installation
URLhaus (abuse.ch)
Base d’URLs observées en train de distribuer un logiciel malveillant.
variable : ABUSECH_AUTH_KEY · configurée sur cette installation
VirusTotal
Agrège le verdict de dizaines de moteurs antivirus et de listes de blocage.
variable : VIRUSTOTAL_API_KEY · non configurée ici
Cloudflare — résolveur de sécurité
Résolveur public qui bloque les domaines classés hameçonnage ou logiciel malveillant. Sans clé.
aucune clé requise · configurée sur cette installation
Une source non configurée ne contribue pas « un peu » : elle ne contribue pas. Son constat porte NON_CONFIGURE, elle est exclue de l’agrégation, et elle apparaît telle quelle dans sources. La confondre avec « rien trouvé » fabriquerait un signal rassurant à partir d’une absence de clé.
Refus et erreurs
// 200 — l'adresse n'a pas été analysée, et c'est le RÉSULTAT
{ "ok": false, "code": "identifiants", "message": "…", "limites": [ … ] }
// codes : vide · schema_dangereux · schema_inconnu · illisible
// hote_absent · trop_longue · identifiants · reseau
// 400 — requête mal formée { "erreur": "requete_invalide", "message": "…" }
// 429 — quota journalier épuisé { "erreur": "quota", "message": "…" }Un refus d’analyse répond 200, pas 4xx. « Cette adresse contient un identifiant avant l’arobase, ne l’ouvrez pas » est l’information la plus utile que l’outil puisse rendre : la livrer sous un code d’erreur la ferait traiter comme une panne par la moitié des clients HTTP.
Quota
120 analyses par adresse IP et par jour. Chaque analyse ouvre de vraies connexions vers le site examiné : sans borne, cette route deviendrait un amplificateur pointé sur une cible choisie par l’appelant. Le quota restant est renvoyé dans quotaRestant.
Ce que l’API ne prouve pas
Aucune analyse ne prouve qu’un lien est sûr
Cet outil compare une adresse à des indices connus ; il ne visite pas le site comme vous le feriez et ne voit pas ce qu’il vous montrera à vous. Un site légitime peut être piraté dans l’heure qui suit cette analyse. Un indice élevé veut dire « rien de suspect trouvé », jamais « vous pouvez y saisir votre mot de passe ».
Une page fabriquée en JavaScript est invisible ici
L’analyse lit le code HTML brut de la page ; elle n’exécute aucun script. Un faux formulaire de connexion construit par du JavaScript après l’ouverture ne sera donc pas vu. Exécuter le code d’un site soupçonné de fraude, sur notre serveur, à la demande d’un inconnu, créerait exactement le risque que tout le reste de l’outil s’emploie à écarter.
Le site peut nous répondre autre chose qu’à vous
L’analyseur s’identifie honnêtement au lieu de se faire passer pour un navigateur. Les campagnes les plus soignées le repèrent et servent alors une page inoffensive : c’est ce qu’on appelle le « cloaking ». Elles distinguent aussi le pays, l’heure et l’appareil. Ce qui est analysé est ce que NOUS avons reçu depuis un serveur américain.
L’âge d’un domaine n’est pas toujours consultable
De nombreux registres nationaux — dont plusieurs en Afrique de l’Ouest — ne publient pas les dates d’enregistrement, et le RGPD masque les titulaires européens. Quand l’information manque, elle est écrite « non disponible » et n’entre dans aucun calcul. Une absence ne compte jamais contre un site.
Le cadenas ne dit pas « site honnête »
Les certificats HTTPS sont gratuits et délivrés en quelques secondes : la quasi-totalité des sites de hameçonnage en possèdent un, parfaitement valide. Le cadenas garantit que personne ne lit la ligne entre vous et le serveur — pas à qui appartient le serveur. C’est pourquoi il pèse peu dans l’indice.
L’adresse analysée est transmise aux bases de menaces
Les sources de réputation fonctionnent en recevant l’adresse à vérifier. Elle est donc envoyée aux services configurés sur cette installation — leur liste exacte figure dans le rapport, sous « Sources ». Si votre lien contient un jeton personnel ou un identifiant privé, tenez-en compte avant de l’analyser.
Ce qui est gardé chez nous, et pendant combien de temps
Votre historique d’analyses ne quitte pas votre navigateur : il n’est envoyé nulle part. Une seule chose est conservée sur notre serveur, pendant six heures : le VERDICT rendu par les bases de menaces, rangé sous une empreinte de l’adresse et non sous l’adresse elle-même. C’est ce qui évite d’interroger ces bases dix fois pour le même lien quand il circule dans un groupe — sans ce cache, elles nous couperaient l’accès, et ce sont les deux seules sources capables d’établir un danger avec certitude.
Ne pas figurer dans une base de menaces ne rassure pas
Ces bases recensent ce qui a DÉJÀ été repéré et signalé. Une page de hameçonnage vit souvent quelques heures et fait ses victimes avant d’y entrer. « Aucun signalement » est donc une absence de mauvaise nouvelle, pas une bonne nouvelle — et c’est écrit ainsi partout dans le rapport.
Aucun taux de réussite n’est annoncé
Les poids utilisés pour calculer l’indice sont des jugements d’ingénierie calibrés sur des campagnes documentées, pas des probabilités mesurées : il n’existe pas ici de corpus de liens étiquetés. Chaque signal est affiché avec ce qu’il établit et ce qu’il n’établit pas, pour que vous puissiez juger vous-même plutôt que de croire un chiffre.