Contexte
Un portfolio de profil cyber qui serait lui-même mal sécurisé, ce serait un comble. J’ai donc traité ce site comme un projet à part entière : chaque choix technique est fait pour réduire la surface d’attaque, et vérifiable par n’importe qui.
Objectif
- Présenter mes projets, mon parcours et mes writeups.
- Viser la meilleure note sur securityheaders.com et Mozilla Observatory.
- N’utiliser aucun traceur, aucun cookie, aucune ressource externe.
- Automatiser entièrement la mise en ligne.
Architecture
Le site est 100 % statique : Astro génère des fichiers HTML, CSS et JavaScript au moment du build. Sur le serveur, il n’y a ni base de données, ni langage exécuté à chaque visite, ni interface d’administration : rien à injecter, rien à pirater de ce côté-là. Le serveur web se contente de servir des fichiers.
La mise en ligne passera par GitLab CI (en cours de mise en place) : à chaque git push,
le pipeline cherchera des
secrets oubliés dans le code, construira le site, vérifiera qu’aucun code inline ne s’y
est glissé, puis le copiera sur le VPS avec un utilisateur dédié aux droits limités. La
détection de secrets est déjà configurée.
Ce que j’ai fait
Une CSP stricte, sans unsafe-inline
La Content Security Policy indique au navigateur d’où il a le droit de charger des scripts et des styles. Ici : uniquement depuis le site lui-même, et jamais de code écrit directement dans la page. Même si quelqu’un réussissait à injecter du HTML, son script ne serait pas exécuté.
Ça impose de la rigueur :
- aucun attribut
style="…", aucun<script>inline, aucunonclick=; - Astro est configuré pour toujours sortir le CSS dans des fichiers séparés ;
- la coloration du code utilise des classes CSS (Prism) plutôt que des styles inline ;
- chaque build est contrôlé : la moindre ligne inline dans le résultat est repérée.
La CSP sera envoyée en en-tête HTTP par le serveur, et non en balise <meta> : c’est
plus complet, et c’est ce que notent les outils d’audit.
Zéro dépendance externe
Les polices sont auto-hébergées, il n’y a ni CDN, ni Google Fonts, ni statistiques de visite. Un visiteur ne contacte que ce serveur : aucune donnée ne part chez un tiers.
JavaScript facultatif
Tout le contenu est lisible sans JavaScript. Les scripts (terminal, thèmes, recherche)
sont des améliorations : désactivez-les, le site fonctionne toujours. Le terminal écrit
ses réponses avec textContent, jamais innerHTML : ce qu’on y tape ne peut pas
devenir du HTML.
Accessibilité et performance
Contrastes AA vérifiés sur chacun des dix thèmes, navigation au clavier, lien d’évitement, animations coupées si le système le demande. Lighthouse : 100 en performance, accessibilité, bonnes pratiques et SEO.
Les brouillons ne fuient pas
Un projet ou un article marqué « brouillon » est visible sur mon poste, mais exclu du build : aucune page, aucun lien, ni dans le sitemap, ni dans le flux RSS. Même règle pour les textes encore à compléter.
Difficultés & solutions
Une page entièrement blanche
- Problème : après l’ajout d’une séquence de démarrage animée, plus rien ne s’affichait. Page blanche, sans aucune erreur dans la console.
- Diagnostic : en désactivant les éléments un par un, j’ai isolé la cause. Le script
posait la classe
bootsur la balise<html>, et une règle CSS.boot { display: none }, prévue pour l’écran de démarrage, s’appliquait aussi… à toute la page. - Solution : renommer la classe posée sur
<html>. - Leçon : un sélecteur de classe ne sait pas à quel élément on pensait. Les classes d’état globales doivent avoir des noms qui ne peuvent pas entrer en collision.
Coloration du code et CSP
- Problème : la coloration syntaxique par défaut d’Astro (Shiki) écrit des
style="…"dans le HTML, que la CSP bloque. - Solution : passer à Prism, qui n’utilise que des classes, et écrire le thème de couleurs en CSS.
- Leçon : une CSP stricte se décide au début d’un projet. L’ajouter à la fin, c’est découvrir tout ce qui l’enfreint.
Ce que j’ai appris
- Concevoir avec une contrainte de sécurité dès le départ plutôt que de l’ajouter après.
- Le fonctionnement réel d’une CSP et des en-têtes de sécurité HTTP.
- L’amélioration progressive : un site qui marche d’abord sans rien, puis mieux avec.
- Automatiser un déploiement avec le minimum de privilèges.
Prochaines étapes
- Mise en ligne sur le VPS : serveur web, HTTPS, en-têtes de sécurité.
- Pipeline GitLab CI complet, avec déploiement automatique.
- Publier ici les notes obtenues sur securityheaders.com et Mozilla Observatory.