Sécurité

Comment Astro et une API PHP ont remplacé un site WordPress monopage

Un site d’une seule page, un formulaire de contact, quelques blocs à mettre à jour de temps en temps : pendant des années, WordPress a été notre réponse par défaut. Pourtant, pour ce type de site, c’est souvent sortir un semi-remorque pour aller chercher le pain.

Nous avons récemment remplacé le site WordPress monopage du food truck moogys-foodtruck.fr par un site statique généré avec Astro, adossé à une petite API REST en PHP. Même périmètre fonctionnel pour le client, mais une surface d’attaque réduite à presque rien et des temps de chargement divisés. Voici comment, et ce que nous y avons gagné.

Le point de départ : un WordPress pour une seule page

Le site existant était un WordPress classique : un thème, un constructeur de pages et une dizaine d’extensions. Fonctionnellement, il proposait :

  • une page unique avec plusieurs sections (présentation, planning, carte du truck, contact) ;
  • un formulaire de contact avec envoi d’e-mail ;
  • une inscription à la newsletter ;
  • quelques contenus modifiés par le client deux ou trois fois par an.

Pour faire tourner ces quatre fonctionnalités, il fallait pourtant PHP et MySQL à chaque visite, des mises à jour hebdomadaires du cœur et des extensions, et une surveillance constante. Chaque requête d’un visiteur, ou d’un robot malveillant, sollicitait toute la pile.

La nouvelle architecture : du statique devant, une API derrière et un Google Sheet

Le principe est simple : tout ce qui peut être calculé à l’avance l’est, et seul ce qui doit vraiment être dynamique passe par un serveur.

Astro pour le front. Astro génère au moment du build, ici exécuté avec Bun pour accélérer la génération, des fichiers HTML, CSS et images optimisés. Par défaut, il n’envoie aucun JavaScript au navigateur ; on n’en ajoute que là où il est utile (ici, le formulaire). Le résultat est un dossier de fichiers statiques, servi directement par le serveur web ou un CDN.

Une API REST en PHP pour le dynamique. Un microframework PHP Slim expose quelques routes : lecture des données à jour, envoi du formulaire de contact, inscription à la newsletter. Quelques centaines de lignes de code, sans base de données ni back-office.

Les données permettant de gérer le menu proposé par le Truck en question, les périodes de vacances, les services relatifs à des prestations privées ou bien encore les lieux de présence du Truck se trouvent dans un Google Sheet. Le client a juste à modifier le contenu de ce Sheet (l’équivalent d’un tableau excel) pour modifier le contenu principal de son site internet. Il est ainsi dispensé d’apprendre une nouvelle technologie comme WordPress.

Des données fraîches pour les visiteurs, un léger décalage pour les robots

Le site combine deux sources de contenu. Les pages HTML sont régénérées régulièrement par un cron qui tourne sur l’hébergement et relance le build Astro avec Bun toutes les 30 minutes. Entre deux passages, le HTML reste figé.

Pour les visiteurs, ce n’est pas un problème : une fois la page chargée, quelques lignes de JavaScript interrogent l’API depuis le navigateur et affichent les données à jour. Ils voient toujours l’état le plus récent.

Les robots d’indexation, eux, lisent en priorité le HTML servi par le serveur ; même quand ils exécutent le JavaScript, c’est souvent en différé. Ils indexent donc la version générée lors du dernier passage du cron, avec un décalage au plus égal à son intervalle. Pour un site vitrine, ce décalage est sans conséquence. Si une donnée doit être indexée rapidement, il suffit de déclencher une régénération à la demande après sa modification.

Iso-périmètre : chaque fonctionnalité retrouvée

L’objectif était clair : le client ne devait rien perdre. Voici comment chaque fonctionnalité a été reprise.

Fonctionnalité Avec WordPress Avec Astro + API PHP
Page et sections Thème + constructeur de pages Composants Astro, HTML généré au build
Formulaire de contact Extension de formulaire Route POST de l’API, envoi SMTP
Newsletter Extension dédiée Route POST relayée vers l’outil d’e-mailing
Mise à jour des contenus Back-office WordPress Modifiés en autonomie par le client (menu, planning, congés, textes)
Anti-spam Extension captcha Champ piège, limitation de débit, captcha sans cookie
Référencement Extension SEO Balises générées par Astro, sitemap automatique

Le client a même gagné en autonomie : plus besoin de se connecter à un back-office WordPress, il met à jour son menu, ses lieux de présence et ses périodes de congés, et même ses textes de présentation, qu’il modifie directement sur son hébergement mutualisé, sans jamais dépendre de nous.

Les gains en sécurité

La meilleure ligne de code, du point de vue de la sécurité, c’est celle qui n’existe pas. En retirant WordPress, nous avons supprimé l’essentiel de la surface d’attaque : plus de /wp-admin, plus de xmlrpc.php, plus d’extensions tierces à surveiller, plus de base de données exposée, et si nous voulons aller plus loin, nous pouvons faire ce que nous appelons du forensic.

Aller plus loin : le forensic

Le forensic, ou analyse forensique, consiste à étudier après coup les traces laissées sur un serveur pour comprendre qui a tenté quoi, quand et comment. Sur un site statique, l’exercice devient particulièrement efficace, car le bruit de fond disparaît.

Le site ne contient plus aucun fichier WordPress. Toute requête vers /wp-login.php, /xmlrpc.php ou /wp-admin ne peut donc pas venir d’un visiteur légitime : c’est forcément un robot qui scanne le web à la recherche de failles. L’ancien site devient en quelque sorte un pot de miel, sans aucun risque puisqu’il n’y a plus rien à compromettre.

Concrètement, l’analyse des journaux d’accès nous permet de :

  • repérer les adresses IP et les réseaux à l’origine des scans, et les bloquer en amont (pare-feu, fail2ban, reverse proxy) ;
  • identifier les outils utilisés grâce aux user-agents et aux chemins testés : extensions vulnérables, sauvegardes oubliées, fichiers .env ou dossiers .git exposés ;
  • suivre l’évolution des campagnes dans le temps et détecter une recrudescence liée à une faille fraîchement publiée ;
  • partager ces informations sur l’ensemble des serveurs que nous hébergeons, pour protéger aussi les sites de nos clients qui tournent encore sous WordPress.

Le forensic porte aussi sur l’intégrité du site. Les fichiers en ligne étant issus d’un build, nous pouvons comparer leurs empreintes (hash) avec celles produites lors de la génération : le moindre fichier modifié ou ajouté sur le serveur est immédiatement repéré. En cas de doute, il suffit de redéployer le build pour revenir à un état sain, sans base de données à restaurer ni extension à nettoyer.

Résistance aux DoS et DDoS

Servir un fichier HTML déjà généré ne coûte presque rien à un serveur web : pas de PHP, pas de requête SQL. Là où un WordPress s’effondre sous quelques centaines de requêtes par seconde, le même serveur encaisse un trafic bien supérieur sur des pages statiques. Placées derrière un CDN ou un reverse proxy avec cache, elles absorbent l’essentiel d’une attaque volumétrique.

Reste l’API, seule partie qui exécute du code. Nous l’avons protégée par une limitation de débit par adresse IP, une taille maximale de requête et des délais d’expiration courts. Même saturée, elle n’emporte pas le site : les pages restent en ligne dans leur dernière version générée, seuls le rafraîchissement des données et le formulaire deviennent temporairement indisponibles.

Protection contre les XSS

Sur WordPress, le risque XSS vient surtout des extensions et des contenus saisis dans le back-office. Ici, il n’y a plus de back-office et les pages sont figées au build. Astro échappe par défaut les valeurs insérées dans le HTML.

Comme il n’y a quasiment plus de JavaScript tiers, nous avons pu appliquer une Content Security Policy stricte, sans unsafe-inline. Côté API, chaque champ est validé et échappé avant d’être inséré dans un e-mail, et seule l’origine du site est autorisée en CORS. Côté navigateur, les données reçues de l’API sont insérées avec textContent et jamais avec innerHTML, pour qu’aucune ne soit interprétée comme du HTML.

Les gains en performances

Une page statique n’a rien à calculer : le serveur répond immédiatement, et le navigateur n’a presque pas de JavaScript à exécuter. Astro optimise aussi les images (formats modernes, dimensions adaptées, chargement différé).

Au-delà du confort de visite, ces gains comptent pour le référencement : les Core Web Vitals font partie des signaux pris en compte par Google. Ils réduisent aussi les ressources consommées sur le serveur, donc l’empreinte de l’hébergement.

Les limites : quand rester sur WordPress

Cette approche n’est pas universelle. WordPress reste le bon choix quand :

  • le client publie souvent et veut être autonome sur ses contenus ;
  • le site comporte de nombreuses pages, un blog actif ou une boutique en ligne ;
  • l’écosystème d’extensions apporte des fonctionnalités qu’il serait coûteux de redévelopper.

Entre les deux, un WordPress utilisé en headless, avec un front statique, combine l’autonomie éditoriale et une bonne partie des gains décrits ici. C’est d’ailleurs l’architecture de ce blog.

Conclusion

Pour un site monopage, remplacer WordPress par Astro et une petite API PHP, c’est garder exactement les mêmes fonctionnalités avec beaucoup moins de choses à maintenir et à protéger. Moins de code exécuté, c’est moins de failles, moins de mises à jour et des pages qui s’affichent plus vite.

Votre site WordPress fait-il bien plus que ce dont vous avez besoin ? Parlons-en, nous vous dirons franchement si une refonte en statique a du sens pour vous.

À lire aussi

Articles sur le même sujet