Aller au contenu

Protections HTTP du web

Les réponses dynamiques SvelteKit reçoivent X-Frame-Options: DENY et X-Content-Type-Options: nosniff, y compris les données, erreurs résolues et redirections. La CSP des documents est générée par SvelteKit : mode: auto produit des nonces sur SSR et des hash en cas de prerender. Le hook conserve cette politique ; il ajoute une politique minimale de refus d’intégration aux autres réponses. Ne pas remplacer le header généré par une chaîne statique qui perdrait les nonces.

  • Scripts : origine de l’application et nonces/hash générés par SvelteKit. Aucune autorisation unsafe-inline ou unsafe-eval pour les scripts ; attributs script interdits sauf l’empreinte exacte de this.__e=event, gestionnaire bénin généré par Svelte pour les images SSR. unsafe-hashes est limité à cette empreinte, sans autorisation générale des gestionnaires inline.
  • Workers : origine de l’application uniquement. MapLibre utilise le worker Vite explicite déjà configuré ; aucune permission blob: pour exécuter du code.
  • Connexions navigateur : même origine et https://api.maptiler.com. Les appels backend passent toujours par le BFF.
  • CSS : même origine, Google Fonts et styles inline nécessaires aux transitions Svelte, attributs existants et styles MapLibre. Cette exception concerne les styles, pas les scripts.
  • Polices : même origine, fonts.gstatic.com et data:. Images : même origine, data:, blob: et HTTPS pour conserver les images distantes du contenu CMS existant.
  • Intégration du site : frame-ancestors 'none'. Objets et sous-frames interdits ; base et formulaires limités à l’origine de l’application.

La recette navigateur transforme uniquement ses réponses de test en Content-Security-Policy-Report-Only avant les scénarios d’enforcement. Elle collecte localement les événements securitypolicyviolation, sans envoyer un rapport contenant des URL d’authentification à un service externe. Elle qualifie hydratation, cartes publiques/admin et traitement GeoJSON par les workers, puis vérifie la politique appliquée et le blocage d’un script injecté sans nonce. Les contrôles CI sans backend couvrent scripts, iframes, erreurs et redirections ; les cartes sont testées séparément avec PocketBase local seedé.

Les scripts Cloudflare observés le 13 octobre 2026 sont servis sous /cdn-cgi/ de la même origine. Aucun script externe n’a été ajouté à la liste pour un service supposé. Après déploiement autorisé, refaire la recette à travers Cloudflare avant d’ajouter un outil analytique, un widget ou une autre source : la qualification locale ne valide pas de futures transformations du CDN. Ne pas élargir les scripts à https: ou à un wildcard pour masquer une violation.

Strict-Transport-Security: max-age=86400 n’est émis que pour les requêtes HTTPS des hôtes vérifiés www.px-playground.fr et preview.px-playground.fr. Le 13 octobre 2026, les vérifications via Cloudflare ont confirmé HTTP 200 et validation TLS 0 sur la production et le health check staging, après le lot TLS strict de backend #121.

La durée initiale est un jour. Après observation et validation opérateur des certificats/renouvellements, proposer une semaine puis un an dans des changements distincts. Aucun includeSubDomains ni preload : messagerie, aliases, previews et futur domaine public ne sont pas engagés automatiquement. Ajouter un nouveau hostname seulement après vérification TLS et routage. Les requêtes HTTP et hôtes non vérifiés ne reçoivent pas cette nouvelle politique.

Le retour arrière consiste à revenir à l’image précédente ; HSTS déjà mémorisé peut continuer jusqu’à expiration. Pour supprimer une politique sur un hôte concerné, servir max-age=0 en HTTPS dans un changement autorisé ; ne pas désactiver TLS pour contourner HSTS. La CSP et les headers des fichiers statiques servis directement par l’adapter ou le CDN nécessitent leur propre configuration si des pages HTML prerendered sont introduites : frame-ancestors en meta est ignoré par les navigateurs.

Validation : make verify, puis E2E_SECURITY_HEADERS=1 make e2e E2E_ARGS='--config playwright.security-headers.config.ts'. Pour la recette cartes, ajouter E2E_SECURITY_BACKEND=1 E2E_BACKEND_URL=http://127.0.0.1:4210 et démarrer uniquement le backend seedé isolé sur ce port loopback. Les parcours d’invitation et de récupération sont aussi retestés sous CSP avec la recette playwright.auth-privacy.config.ts.

Sources : CSP SvelteKit, CSP MapLibre.