Hidden Link Guard
Plugin WordPress : détecte et nettoie les liens masqués injectés en base de données (spam SEO), avec alerte au tableau de bord et nettoyage réversible.
by Wadie Aroua · github.com/waddou/hidden-link-guard · website
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/waddou/hidden-link-guard/releases/download/v1.0.3/hidden-link-guard.zipReadme
Hidden Link Guard
Plugin WordPress qui détecte et nettoie les injections de spam SEO en base de données : les blocs HTML rendus invisibles au visiteur mais lus par les moteurs de recherche, insérés dans le contenu des articles.
Développé par Wadie Aroua — noticiel.com
<div style="position:absolute;left:-9999px;top:-9999px;width:1px;height:1px;overflow:hidden">
<p><a href="https://domaine-spam.tn/">domaine-spam</a></p>
</div>
<div style="display: none;">
<ul><li><a href="https://autre-spam.com" rel="dofollow">autre-spam</a></li></ul>
</div>
Installation
- Copier le dossier
hidden-link-guard/danswp-content/plugins/. - Activer « Hidden Link Guard » dans Extensions.
- Ouvrir Link Guard dans le menu d'administration et cliquer sur Lancer un scan.
Ce que fait le plugin
- Alerte en haut de toutes les pages de
wp-admindès qu'une injection est en attente de traitement, plus un widget sur le tableau de bord. - Scan de l'ensemble de la base, par lots, avec barre de progression.
- Nettoyage en un clic, global ou ligne par ligne.
- Restauration de n'importe quelle valeur nettoyée : chaque original est sauvegardé avant modification.
- Scan planifié chaque nuit et alerte e-mail en cas de détection.
- Export CSV du rapport.
Ce qui est nettoyé exactement
Seule la portion injectée est retirée. Jamais l'article, jamais le champ.
Le plugin localise la balise ouvrante du bloc masqué, compte la profondeur d'imbrication pour trouver sa fermeture exacte, et supprime uniquement cet intervalle. Le reste du champ est réécrit à l'identique, octet pour octet — les tests le vérifient en contrôlant que le résultat est une sous-chaîne exacte de la valeur d'origine.
L'écriture se fait directement en base plutôt que par wp_update_post, dont les
filtres (kses, wpautop) reformateraient des parties saines du contenu.
Comment la détection fonctionne
Une liste de domaines spam serait obsolète au scan suivant. Le plugin repère la signature structurelle de l'injection. Un bloc n'est signalé que si :
- son style inline le rend invisible —
display:none,visibility:hidden,opacity:0,font-size:0, positionnement hors écran (left:-9999px),text-indenttrès négatif, dimensions1px/0avecoverflow:hidden,clipouclip-path; et - il contient au moins un lien vers un domaine externe au site.
La seconde condition est le garde-fou principal : un bloc caché sans lien
sortant n'est jamais signalé. Les conteneurs d'accessibilité légitimes
(screen-reader-text, sr-only, visually-hidden, skip-link…) sont exclus
d'office — WordPress core en utilise.
Chaque bloc reçoit un score ; le signalement démarre à 50. rel="dofollow"
(attribut non standard, propre aux outils de spam) et le positionnement hors
écran pèsent le plus lourd. Le score est affiché pour vous laisser arbitrer les
cas limites.
Emplacements analysés
| Table | Champs |
|---|---|
posts |
post_content, post_excerpt, post_title (hors révisions et médias) |
postmeta |
meta_value |
options |
option_value (hors transients) |
comments |
comment_content |
usermeta |
meta_value |
term_taxonomy |
description |
Les valeurs sérialisées sont désérialisées, nettoyées récursivement, puis re-sérialisées : un simple remplacement de texte corromprait les longueurs encodées dans la structure.
Tests
Les deux suites s'exécutent en PHP pur, sans installation WordPress :
php tests/test-detector.php # détection, préservation du contenu, faux positifs
php tests/test-serialized.php # intégrité des valeurs sérialisées
Ou les deux d'un coup :
bash tests/run-all.sh
La suite de détection tourne sur un article réellement contaminé
(tests/fixtures/injected-post.html) et vérifie notamment que les 9 blocs
injectés partent, que l'article reste intact, et que huit scénarios de faux
positifs ne déclenchent aucun signalement.
Personnalisation
Le filtre hlg_own_hosts permet d'ajouter des domaines considérés comme
internes — utile si votre site publie légitimement des liens vers vos autres
domaines et que ceux-ci apparaissent dans des blocs masqués :
add_filter( 'hlg_own_hosts', function ( $hosts ) {
$hosts[] = 'mon-autre-domaine.fr';
return $hosts;
} );
Avant de nettoyer en masse
Le plugin sauvegarde chaque valeur d'origine et permet de la restaurer, mais une sauvegarde complète de la base avant une première campagne de nettoyage reste la bonne pratique.
Traiter la cause, pas seulement le symptôme
Nettoyer la base ne referme pas la porte d'entrée. Si les injections réapparaissent après un scan propre, le vecteur est toujours actif : extension ou thème vulnérable, compte administrateur compromis, fichier PHP porte dérobée, identifiants FTP ou SQL dérobés.
Sur un hébergement OVH
La procédure détaillée figure dans readme.txt, section
« Traiter la cause sur un hébergement OVH ». En résumé :
- Réinitialiser tous les identifiants depuis l'espace client OVH : FTP/SFTP
(en supprimant les utilisateurs additionnels non créés par vous), base de
données, compte OVH avec double authentification. Côté WordPress, changer les
mots de passe administrateurs et regénérer les clés de sécurité de
wp-config.php— cela déconnecte toutes les sessions actives, y compris celle d'un intrus. - Activer le pare-feu applicatif sur mutualisé, via un fichier
.ovhconfigà la racine contenanthttp.firewall=security. Ce fichier fixe aussi la version PHP : une version en fin de vie est un vecteur d'entrée courant. - Dater l'intrusion via les logs de l'hébergement, consultables depuis
l'espace client. Chercher les POST vers des fichiers PHP inhabituels
(notamment dans
wp-content/uploads/), les accès àxmlrpc.php, les rafales surwp-login.php. - Restaurer une sauvegarde OVH antérieure à cette date. Restaurer la base seule ne supprime pas une porte dérobée dans les fichiers, et l'inverse est tout aussi vrai.
- Chercher les portes dérobées : réinstaller le cœur WordPress depuis
l'administration, repérer les fichiers PHP dans les dossiers d'upload et de
cache, inspecter
wp-config.phpet les.htaccess. Bloquer l'exécution de PHP danswp-content/uploads/. - Vérifier les tâches CRON de l'hébergement : une tâche inconnue peut réinjecter le spam après chaque nettoyage.
Le scan planifié quotidien sert précisément à détecter une réapparition, signe que le vecteur est encore ouvert.
Changelog
Voir CHANGELOG.md.
Licence
GPL-2.0-or-later. Voir LICENSE.
Read the full README on GitHub →
Releases
| Tag | Published | Asset | Downloads |
|---|---|---|---|
| v1.0.3 | Jul 27, 2026 | hidden-link-guard.zip | 1 |