web-dev-qa-db-fra.com

Cookies sécurisés et utilisation mixte du site https / http

De nombreux sites semblent prendre en charge https mais n'utilisent pas de cookies sécurisés. Je souhaite que mon site utilise des cookies sécurisés mais autorise l'accès à certains contenus à l'aide de http.

Un moyen judicieux de le faire semble être d'avoir un cookie sécurisé pour la session réelle, et un cookie non sécurisé qui est juste un indicateur pour dire si l'utilisateur est connecté ou non (pour afficher différentes choses dans l'en-tête, comme un lien de déconnexion au lieu d'un lien de connexion). Ce cookie ne contiendrait aucune information de session "réelle" et est juste pour que le site puisse afficher les pages légèrement différemment pour les utilisateurs connectés par rapport à ceux déconnectés sur les parties http du site.

Avoir tout le site en https est une autre option, mais cela semble être un peu plus lent que http simple et n'est donc pas vraiment idéal.

Pourquoi les sites n'utilisent-ils pas ce type de configuration et n'ont-ils pas de cookies sécurisés? La possibilité de vol de cookies semble faire des cookies sécurisés une nécessité de nos jours. Existe-t-il une meilleure façon de réaliser la même chose?

51
David Gardner

La solution que vous proposez semble fonctionner, tant que cela ne vous dérange pas que des personnes non autorisées puissent voir la partie non sécurisée (http) du site "comme si elles étaient connectées" - c'est-à-dire tant que la partie http du site ne contient aucune information sensible, et la seule différence entre les utilisateurs connectés et non connectés est quelque chose d'inoffensif dans l'en-tête.

La raison pour laquelle il n'est pas utilisé très souvent peut être l'une des suivantes:

  • Ce scénario n'est peut-être pas très courant. Habituellement, si vous vous souciez suffisamment de sécuriser une partie de votre site, vous restreindrez la session de connexion uniquement à cette partie sécurisée, ou vous ferez en sorte que l'ensemble du site utilise toujours HTTPS (comme Paypal).
  • Il existe des solutions préexistantes qui sont sécurisées et qui sont capables de plus que cela, par exemple, connecter quelqu'un à un formulaire de connexion HTTPS et maintenir cette session tout en les retransférant vers HTTP. OpenID est un exemple. Pensez également à flickr ou gmail: leur page de connexion est toujours HTTPS, mais une fois la session démarrée, vous migrez à nouveau vers HTTP tout en maintenant la session en toute sécurité.

Mise à jour (août 2014)

Depuis que j'ai écrit cela en 2009, la pratique d'avoir une connexion sécurisée pour l'écran de connexion mais de revenir à HTTP une fois connecté a pratiquement disparu.

Les frais généraux liés à l'utilisation de HTTPS sur le côté ne sont plus considérés comme un problème majeur. Le nouveau protocole SPDY mis au point par Google (maintenant transformé en HTTP/2) est pris en charge entre les navigateurs et par les principaux serveurs Web et améliore la vitesse HTTPS.

Enfin, la confidentialité est considérée comme plus importante que jamais, même pour les actions qui ne sont pas essentielles à l'authentification, telles que la rédaction de commentaires, le téléchargement de photos, etc.

Google a même déclaré récemment que les sites HTTPS uniquement commenceraient à bénéficier du classement des moteurs de recherche.

31
thomasrutter

Du point de vue de la sécurité, vous ne devez jamais faire confiance à un contenu envoyé via une connexion non sécurisée. Donc, dans cet esprit, il est sûr d'utiliser un cookie envoyé via une connexion non cryptée uniquement si le coût du vol ou de la mauvaise utilisation de ce cookie est d'environ zéro.

Dans cet esprit, la plupart des sites sont conçus de telle sorte que les données ne soient pas autorisées à "fuir" entre les canaux. Après tout, les données provenant du côté chiffré sont généralement privilégiées et ne devraient donc pas être autorisées dans le canal normal, tandis que les données provenant du canal non chiffré sont potentiellement usurpées, et ne devrait pas faire confiance.

Si vous avez des données qui ne correspondent pas à ces généralisations, n'hésitez pas à les utiliser à votre guise.

11
tylerl

Le transfert de cookies de session via HTTP me dérange depuis un moment. Je pense que la technique que vous avez décrite est la seule manière saine de sécuriser les cookies tout en permettant aux utilisateurs connectés de parcourir les pages HTTP comme s'ils étaient connectés. Cependant, j'ai rarement vu cela implémenté.

Pourquoi les sites n'utilisent-ils pas ce type de configuration et n'ont-ils pas de cookies sécurisés?

Je pense que la principale raison du manque d'adoption est gestion des risques :

  • Voler des jetons de session via l'écoute est beaucoup plus difficile que par ex. script intersite (en supposant qu'il existe une vulnérabilité). Vous devez avoir accès au réseau (par exemple, LAN ou FAI de l'utilisateur). Ainsi, selon la priorisation basée sur les risques, les développeurs devraient d'abord s'attaquer aux problèmes XSS car ils fournissent une surface d'attaque beaucoup plus grande (la probabilité d'une attaque est beaucoup plus élevée).
  • Il en va de même pour la correction CSRF et UI (aka click-jacking).
  • Si l'impact commercial des sessions piratées est élevé (par exemple, le stockage de cartes de crédit pour une utilisation ultérieure dans une boutique en ligne), il serait préférable de restreindre l'ensemble de votre site au HTTPS.

Une autre raison peut être liée aux problèmes d'utilisation: avec le schéma que vous proposez, vous gérez efficacement deux sessions simultanées pour un seul utilisateur. C'est assez facile tant que l'indicateur de connexion est le seul état stocké dans la session non sécurisée. Si vous pouvez également modifier des paramètres comme la langue et le pays à partir des deux sessions, cela peut devenir compliqué (à mettre en œuvre ou à utiliser).

Existe-t-il une meilleure façon de réaliser la même chose?

De Le manuel du pirate d'applications Web :

Si des cookies HTTP sont utilisés pour transmettre des jetons, ceux-ci doivent être marqués comme secure pour empêcher le navigateur de l'utilisateur de les transmettre via HTTP. Si possible, HTTPS doit être utilisé pour chaque page de l'application, y compris le contenu statique tel que les pages d'aide, les images, etc.

Sérieusement, faites en sorte que l'ensemble du site utilise HTTPS. Il y a quelques années, cela n'était peut-être pas possible, principalement parce que les CDN ne fournissaient pas de support HTTPS. Mais aujourd'hui, il s'agit principalement d'équilibrer les coûts de développement et d'exploitation.

9
Pankrat

Je suis pleinement conscient que la pratique recommandée consiste à forcer simplement SSL sur l'ensemble du site. Cependant, il existe certainement des cas uniques où la possibilité de choisir entre HTTP et HTTPS pourrait être utile.

Je rencontrais un scénario similaire à celui de @Dsavid Gardner. Mon entreprise utilise un fournisseur tiers pour gérer la partie magasin de notre site, et ce magasin réside sur le sous-domaine " https://store.mysite.com ". Nous avons 15 ans de contenu vidéo et notre fournisseur actuel de gestion vidéo se casse lorsqu'une vidéo est intégrée dans un SSL. (Je suppose que cela tire des ressources des domaines HTTP, mais c'est un autre problème pour un autre jour)

Bien sûr, je pourrais acheter un SSL et passer par le processus de débogage de deux fournisseurs tiers, ainsi que faire une recherche et remplacer sur toute notre base de données (ou un hack de fichier .htaccess, mais je m'éloigne du sujet) pour corriger n'importe quelle ressource HTTP des liens, juste pour pouvoir avoir un message dans l'en-tête disant "Bienvenue 'YourName'", mais cela semble juste exagéré.

Voici une solution Javascript simple que j'ai trouvée qui définit un cookie non sécurisé à l'échelle du site basé sur les cookies sécurisés qui sont déjà définis.

Tout d'abord, j'ai saisi quelques fonctions de cookie javascript . Allez-y et mettez ce code dans la partie sécurisée de votre site:

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)===' ') { 
            c = c.substring(1,c.length);
        }
        if (c.indexOf(nameEQ) === 0) {
            return c.substring(nameEQ.length,c.length);
        }
    }
    return null;
 }
 function setCookie(cname, cvalue, exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires="+d.toUTCString();

    /* Note, the W3 documents where I got this code didn't include the
    option to set the domain. I added this and it allows the cookie 
    to be shared across sub-domains. Be sure not to add "www" */
    document.cookie = cname + "=" + cvalue + "; " + expires + "; domain=.yourdomain.com";
 }
 /*Now we check our cookies on our secure server to find out if the user is
 logged in or not. In my case, the First Name is stored as a cookie. */
 var firstNameCookie = readCookie("the-secure-cookie-name");
 //
 if(!firstNameCookie){
    /* If the cookie doesn't exist, then the person isn't logged in. Add 
    conditional logic here if you'd like (such as deleting any current 
    logged in cookies from the HTTP portion of the site) */
 }
 else {
    /* otherwise, we have a successful login. By grabbing the cookie via 
    this javascript resting on the secure server, we haven't compromised our 
    security. However, if we set a cookie with javascript right now, it 
    won't be a secure cookie by default and we'll have access to it with 
    HTTP on the subdomain */
    setCookie("HTTPfirstName", firstNameCookie, 1.5);
 }

 */The clients first name is now accessible across subdomains in the cookie
  entitled "HTTPfirstName" */

Dans ce cas, la seule chose que nous avons transmise à notre serveur HTTP est le prénom du client. Cependant, si vous souhaitez encore plus de sécurité, vous pouvez définir les paramètres de votre serveur pour autoriser l'accès à certains cookies (par exemple, "firstNameCookie) par une requête HTTP, ce qui ajoute une couche de protection supplémentaire. Vous pouvez apprendre comment faire ici

Bien sûr, ce n'est pas la solution la plus idéale. À l'avenir, je prévois d'implémenter SSL à l'échelle du site, mais avoir une simple fonction javascript pour le remplacer en attendant est sûr d'avoir Nice.

1
Lucas