
# Sécurité web des pages hébergées et de l'API front

La connexion hébergée, le portail de compte, les pages d'e-mail (vérification, réinitialisation de mot de passe, invitation) et l'API du navigateur qu'elles appellent suivent une base de sécurité web fixe sur chaque offre. Ces protections ne sont pas des paramètres que vous pouvez désactiver. Le seul paramètre que vous contrôlez est la liste des origines web autorisées à appeler les points de terminaison OAuth depuis le navigateur.

## Falsification de requête inter-sites (CSRF)

Les requêtes qui modifient un état sont vérifiées avant toute lecture ou modification :

- **Contrôle de l'origine.** Une requête modifiant un état adressée à l'API de connexion hébergée ou à une page de vérification ou de réinitialisation doit porter un en-tête `Origin` strictement identique à l'hôte de connexion de l'environnement. Toute autre origine est refusée avec `origin_not_allowed`.
- **Écran de consentement.** Un envoi de formulaire sur l'écran de consentement est refusé lorsque son `Origin` n'est pas l'hôte propre de la page, ou lorsque `Sec-Fetch-Site` est présent et différent de `same-origin`.
- **Jetons de formulaire.** Chaque transaction de connexion et chaque formulaire d'e-mail dispose de son propre jeton CSRF, dérivé avec HMAC-SHA256 à partir d'une clé propre à l'environnement. L'API de connexion l'attend dans l'en-tête `Idp-Csrf-Token` ; le jeton d'un formulaire ne fonctionne pas pour un autre. Les jetons sont comparés en temps constant.
- **Cookies.** Les cookies qui portent l'état de connexion utilisent `SameSite=Lax` (voir ci-dessous), de sorte qu'une requête lancée depuis un autre site ne les envoie pas.

## Requêtes inter-origines (CORS)

Le CORS n'est traité que sur les points de terminaison OAuth appelés par une application navigateur : les points de terminaison de jeton, de révocation, de requête d'autorisation poussée et de userinfo. Il ne s'applique qu'aux applications monopage publiques (type `spa`).

- Définissez les origines autorisées par application avec `allowed_web_origins` (`https://host[:port]`, au maximum 20, sans caractères génériques). Voir [Créer une application](/docs/api/management/applications/create).
- La requête de pré-vérification (preflight) du navigateur n'indique pas quelle application appelle, elle reçoit donc une réponse fondée sur l'union des origines autorisées des applications monopage publiques actives de l'environnement. La requête réelle est ensuite contrôlée par rapport à la liste d'origines de l'application appelante.
- Une origine absente de la liste de cette application est refusée avec `403 origin_not_allowed` et ne reçoit aucun en-tête `Access-Control-Allow-Origin`.
- Une origine autorisée est renvoyée à l'identique. `*` et `null` ne sont jamais envoyés, `Access-Control-Allow-Credentials` n'est jamais envoyé, et chaque réponse inter-origine porte `Vary: Origin`.
- Les requêtes provenant de l'hôte de connexion lui-même ne sont pas inter-origines et ne sont pas concernées.

## Redirections après connexion

Si vous utilisez le SDK Next.js, `returnTo` doit être un chemin de votre propre application. Une URL complète ou une valeur telle que `//evil.example` est ignorée, et l'utilisateur atterrit sur `/`. Voir [SDK Next.js](/docs/sdk/nextjs).

## En-têtes de sécurité

Les pages hébergées définissent ces en-têtes sur chaque réponse :

| En-tête | Valeur |
|---|---|
| `Content-Security-Policy` | `default-src 'none'`; scripts uniquement avec un nonce frais par réponse; `style-src 'self'`; `connect-src 'self'`; `frame-ancestors 'none'`; `base-uri 'none'`; `object-src 'none'`; `upgrade-insecure-requests`; Trusted Types requis pour les scripts |
| `Reporting-Endpoints` et `report-to` | Les violations de politique sont signalées à `/u/csp-report` sur le même hôte |
| `X-Frame-Options` | `DENY` : les pages hébergées ne peuvent pas être intégrées dans un cadre |
| `X-Content-Type-Options` | `nosniff` |
| `Referrer-Policy` | `no-referrer` |
| `Cross-Origin-Opener-Policy` | `same-origin` |
| `Permissions-Policy` | Caméra, micro, géolocalisation, paiement, USB, série, HID et Bluetooth sont désactivés ; les requêtes de clé d'accès sont autorisées pour la page elle-même |
| `Cache-Control` | `no-store` |

La politique n'autorise aucun script en ligne ni aucun mot-clé `unsafe-`. Les envois de formulaires sont limités à l'hôte propre de la page ; sur l'écran de consentement, la politique autorise aussi l'adresse de redirection de l'application qui demande l'accès, afin que la décision puisse lui revenir.

Le point de terminaison de signalement n'accepte que les rapports de violation du navigateur d'au plus 8 Kio et est limité en débit par adresse IP. Les rapports sont comptabilisés par directive. Ils ne contiennent ni chaîne de requête, ni fragment, ni information sur l'utilisateur lorsqu'ils sont journalisés.

### Strict-Transport-Security

- Les hôtes d'environnement sous `keenauth.app` envoient `max-age=63072000; includeSubDomains`.
- Un [domaine personnalisé](/docs/guides/custom-domains) envoie uniquement `max-age=63072000`, sans `includeSubDomains`. KeenAuth ne peut pas décider pour les autres sous-domaines de votre domaine : ce choix vous revient.

## Cookies

Les cookies d'état de connexion sont nommés avec le préfixe `__Host-`, de sorte qu'un navigateur ne les accepte que sur HTTPS, avec `Path=/` et sans attribut `Domain`. Ils ne peuvent pas être définis depuis un sous-domaine voisin.

| Cookie | Attributs | Finalité |
|---|---|---|
| `__Host-idp_session` | `Secure`, `HttpOnly`, `SameSite=Lax` | La session de l'utilisateur. Sa durée de vie prend fin à l'expiration absolue de la session |
| `__Host-idp_device` | `Secure`, `HttpOnly`, `SameSite=Lax` | Reconnaissance de l'appareil |
| `__Host-idp_ltx` et `__Host-idp_azr_*` | `Secure`, `HttpOnly`, `SameSite=Lax` | Lie une tentative de connexion ou d'autorisation au navigateur qui l'a lancée |
| `__Host-idp_fed_bind` | `Secure`, `HttpOnly`, `SameSite=None` | Liaison de courte durée pour la connexion SAML d'entreprise. Le fournisseur d'identité renvoie les données depuis un autre site, donc `Lax` le supprimerait |

Les valeurs des cookies ne sont pas lisibles par les scripts de la page (`HttpOnly`).

## Voir aussi

- [Sécurité de l'accès au tableau de bord](/docs/security/dashboard-access)
- [Isolation des locataires](/docs/security/tenant-isolation)
- [Personnaliser vos pages de connexion](/docs/guides/branding)
