Nginx: n’autorise que certains cookies dans la réponse http

J’utilise playframework et nginx. playframework peut append les cookies suivants à la réponse http: PLAY_SESSION, PLAY_FLASH, PLAY_LANG.
Je veux m’assurer que seuls les cookies ci-dessus (PLAY_ *) sont autorisés au niveau nginx. S’il y a d’autres cookies (disons qu’ils sont ajoutés accidentellement), ils doivent être supprimés par nginx.
Comment puis-je autoriser uniquement les cookies prédéfinis dans la réponse http de nginx?

PS: S’il n’est pas possible de résoudre ce problème dans nginx, je dois corriger en utilisant playframework.

Comment fonctionnent les cookies?

Tout d’abord, établissons quels sont les cookies – ce sont de petites informations cachées qui vous permettent de conserver l’état de votre site Web pour un utilisateur donné. Ces cookies sont souvent utilisés pour suivre les utilisateurs, conserver la session et stocker des informations de préférence mineures pour le site.

  • Set-Cookie tête de réponse HTTP Set-Cookie (du serveur au client)

    Les cookies peuvent être définis par le serveur via l’en Set-Cookie tête de réponse Set-Cookie ( avec un en-tête distinct pour chaque cookie ) ou, une fois la page transférée du serveur vers le client, via JavaScript.

    Notez que la configuration des cookies est un travail assez complexe – ils ont des dates d’expiration, des parameters http / https, un chemin, etc. – d’où la nécessité apparente d’utiliser un en Set-Cookie tête Set-Cookie distinct pour chaque cookie.

    Cette exigence d’avoir un en-tête séparé n’est généralement pas un problème, car les cookies ne sont pas censés être modifiés tout cela souvent, car ils stockent généralement des informations très minimales, comme un identifiant de session, les informations lourdes étant stockées dans un firebase database sur le serveur.

  • Cookie tête de requête HTTP Cookie (du client au serveur)

    Quelle que soit la façon dont ils ont été définis pour la première fois, les cookies étaient alors inclus dans les demandes ultérieures éligibles adressées au serveur par le client, en utilisant l’en-tête de demande de Cookie , avec une liste complète de cookies éligibles dans un en-tête.

    Notez que, en tant que tels, ces cookies envoyés par le client au serveur sont une simple liste de paires nom / atsortingbut, sans aucune information supplémentaire sur les cookies sous-jacents qui stockent ces atsortingbuts du côté client (par exemple, les dates d’expiration , le paramètre http / https et les chemins d’access sont enregistrés en interne par le client, mais sans être révélés dans les requêtes ultérieures au serveur).

    Cette concision du champ d’en-tête de demande de Cookie est importante car, une fois définie, les cookies éligibles seront ultérieurement inclus dans toutes les demandes à venir pour toutes les ressources avec la combinaison système / domaine / chemin éligible.


Problèmes de mise en cache avec les cookies.

Le problème normal de l’utilisation des cookies, en particulier dans le contexte de l’accélération et de nginx , est le suivant:

  • les cookies invalident le cache par défaut (par exemple, sauf si vous utilisez proxy_ignore_headers Set-Cookie; ),

  • ou, si vous effectuez une configuration bâclée, les cookies risquent de gâcher votre cache

    • Par exemple, le client pouvant transmettre des cookies à l’amont en l’absence de proxy_set_header Cookie ""; ,

    • ou, via le serveur insistant pour définir un cookie en l’absence de proxy_hide_header Set-Cookie; .


Comment nginx gère les cookies?

  • Cookie du client

    Notez que nginx prend en charge l’examen des cookies que le client lui envoie (dans l’en-tête de la demande de Cookie ) via le schéma $cookie_name .

    Si vous souhaitez limiter le client à envoyer uniquement certains cookies, vous pouvez facilement reconstruire l’en-tête Cookie en fonction de ces variables, et n’envoyer que ceux que vous souhaitez à l’amont (en utilisant proxy_set_header comme ci-dessus).

    Ou bien, vous pouvez même prendre des décisions en fonction du cookie pour décider en amont de laquelle envoyer la demande, ou pour avoir un proxy_cache_key par utilisateur / par session, ou pour prendre des décisions de contrôle d’access basées sur les cookies.

  • Set-Cookie du backend

    En ce qui concerne l’envoi des cookies en amont, vous pouvez bien sûr décider de bloquer tout cela pour améliorer considérablement les caractéristiques de mise en cache (si applicable à votre application ou à des parties de celle-ci) ou réparer le domaine et / ou le proxy_cookie_domain avec proxy_cookie_domain . / ou proxy_cookie_path , respectivement.

    Sinon, il est généralement trop tard pour prendre une autre décision de routage – la demande a déjà été traitée par le serveur en amont sélectionné et la réponse est prête à être diffusée – il ne semble donc pas y avoir de moyen de rechercher ces cookies Set-Cookie individuels par des moyens normaux dans nginx (sauf si vous souhaitez utiliser des modules tiers, ou lua ou perl), car il est déjà trop tard pour prendre des décisions de routage importantes pour une demande terminée.

    Fondamentalement, ces cookies Set-Cookie ont plus à voir avec le contenu qu’avec la façon dont il est servi ou routé, il ne semble donc pas approprié d’avoir une fonctionnalité intégrée pour les examiner via nginx.

    (Si vous devez prendre des décisions de routage une fois la requête terminée, nginx prend en charge X-Accel-Redirect , ainsi que d’autres en-têtes spéciaux.)

    Si votre problème est la sécurité, alors, comme je l’ai indiqué ci-dessus, le développeur en amont peut déjà utiliser JavaScript pour définir tous les cookies supplémentaires comme il veut, alors essayez effectivement d’utiliser nginx pour limiter certains, mais pas tous. Set-Cookie réponses aux Set-Cookie du serveur sont une sorte de tentative inutile dans le monde réel (car il n’y a guère de différence entre les cookies définis via JavaScript et Set-Cookie ).


En résumé:

  • vous pouvez facilement examiner et reconstruire l’en-tête de Cookie envoyé par le client au serveur avant de le transmettre au backend, et n’inclure que les cookies autorisés dans le backend de demande en amont,

  • mais, à moins que vous ne souhaitiez utiliser lua / perl ou avoir votre propre module nginx (et éventuellement mettre le code JavaScript en quarantaine à partir des pages que vous diffusez), vous ne pouvez pas renvoyer au client uniquement certains en Set-Cookie têtes Set-Cookie avec un stock nginx.conf – avec les en Set-Cookie têtes Set-Cookie , il s’agit d’une situation tout ou rien, et il ne semble pas y avoir de cas d’utilisation suffisant pour une approche distincte.

Pour une solution Nginx, il peut être utile de poser la question sur serverfault . Voici une solution potentielle via Play Framework.

 package filters import javax.inject._ import play.api.mvc._ import scala.concurrent.ExecutionContext @Singleton class ExampleFilter @Inject()(implicit ec: ExecutionContext) extends EssentialFilter { override def apply(next: EssentialAction) = EssentialAction { request => next(request).map { result => val cookieWhitelist = List("PLAY_SESSION", "PLAY_FLASH", "PLAY_LANG") val allCookies = result.newCookies.map(c => DiscardingCookie(c.name)) val onlyWhitelistedCookies = result.newCookies.filter(c => cookieWhitelist.contains(c.name)) result.discardingCookies(allCookies: _*).withCookies(onlyWhitelistedCookies: _*) } } } 

Cette solution utilise la manipulation des filtres et des Result . Ne testez pas les effets néfastes sur la performance.