ten jest szybki:
Możesz myśleć, że tak powinno być, ale tak naprawdę wcale nie jest!
Jakie są dozwolone znaki zarówno w nazwie pliku cookie, jak i wartości?
Według starożytnego Netscape cookie_spec cały NAME=VALUE
ciąg to:
sekwencja znaków z wyłączeniem średnika, przecinka i białych znaków.
Tak -
powinno działać, i wydaje się być OK w przeglądarkach, które tu mam; gdzie masz z tym problem?
Implikując powyższe:
=
jest to legalne, ale potencjalnie dwuznaczne. Przeglądarki zawsze dzielą nazwę i wartość na pierwszy =
symbol w ciągu, więc w praktyce możesz umieścić =
symbol w WARTOŚCI, ale nie NAZWĘ.
Co nie jest wspomniane, ponieważ Netscape był okropny w pisaniu specyfikacji, ale wydaje się być konsekwentnie obsługiwany przez przeglądarki:
NAZWA lub WARTOŚĆ mogą być pustymi ciągami
jeśli =
w łańcuchu nie ma żadnego symbolu, przeglądarki traktują go jako plik cookie o nazwie pustego łańcucha, tzn. Set-Cookie: foo
jest taki sam jak Set-Cookie: =foo
.
gdy przeglądarki wysyłają plik cookie o pustej nazwie, pomijają znak równości. Więc Set-Cookie: =bar
zaczyna Cookie: bar
.
przecinki i spacje w nazwach i wartościach faktycznie działają, chociaż spacje wokół znaku równości są przycięte
znaki kontrolne ( \x00
na \x1F
plus \x7F
) są niedozwolone
To, czego nie wspomniano, a przeglądarki są całkowicie niespójne, to znaki spoza ASCII (Unicode):
- w Operze i Google Chrome są one kodowane w nagłówkach Cookie za pomocą UTF-8;
- w IE używana jest domyślna strona kodowa komputera (specyficzna dla ustawień regionalnych i nigdy UTF-8);
- Firefox (i inne przeglądarki oparte na Mozilli) same używają niskiego bajtu każdego punktu kodowego UTF-16 (więc ISO-8859-1 jest OK, ale wszystko inne jest zniekształcone);
- Safari po prostu odmawia wysłania pliku cookie zawierającego znaki spoza ASCII.
dlatego w praktyce w plikach cookie nie można w ogóle używać znaków spoza ASCII. Jeśli chcesz korzystać z Unicode, kodów sterujących lub innych dowolnych sekwencji bajtów, cookie_spec wymaga użycia schematu kodowania ad-hoc według własnego wyboru i zasugerowania kodowania URL-a (wyprodukowanego przez JavaScript encodeURIComponent
) jako rozsądnego wyboru.
Pod względem faktycznych standardów podjęto kilka prób skodyfikowania zachowania plików cookie, ale jak dotąd żadne nie odzwierciedla rzeczywistego świata.
RFC 2109 to próba skodyfikowania i naprawy oryginalnego pliku cookie Netscape. W tym standardzie wiele innych znaków specjalnych jest niedozwolonych, ponieważ używa on tokenów RFC 2616 (a -
jest tam nadal dozwolone) i tylko wartość może być określona w cudzysłowie z innymi znakami. Żadna przeglądarka nigdy nie wdrożyła ograniczeń, specjalnej obsługi cytowanych ciągów znaków i znaków zmiany znaczenia ani nowych funkcji w tej specyfikacji.
RFC 2965 był kolejnym krokiem w tym kierunku, uporządkując 2109 i dodając więcej funkcji w ramach schematu „ciasteczka w wersji 2”. Nikt też tego nie wdrożył. Ta specyfikacja ma takie same ograniczenia tokenów i cytowanych ciągów jak wcześniejsza wersja i jest to tak samo dużo bzdur.
RFC 6265 to próba wyczyszczenia historycznego bałaganu z czasów HTML5. Nadal nie pasuje dokładnie do rzeczywistości, ale jest o wiele lepszy niż wcześniejsze próby - to przynajmniej odpowiedni podzbiór obsługiwanych przeglądarek, nie wprowadzający żadnej składni, która powinna działać, ale nie działa (jak poprzedni ciąg cytowany) .
W 6265 nazwa pliku cookie jest nadal określana jako RFC 2616 token
, co oznacza, że możesz wybierać z alfanum plus:
!#$%&'*+-.^_`|~
W wartości cookie formalnie zakazuje (filtrowane przez przeglądarki) znaki kontrolne i (niekonsekwentnie) znaki spoza ASCII. Zachowuje zakaz cookie_spec dotyczący spacji, przecinków i średników, a także dla zgodności z wszelkimi słabymi idiotami, którzy faktycznie wdrożyli wcześniejsze RFC, zakazał także odwrotnego ukośnika i cytatów, innych niż cytaty zawijające całą wartość (ale w takim przypadku cytaty są nadal uważane za część wartość, a nie schemat kodowania). Dzięki temu masz alfanum plus:
!#$%&'()*+-./:<=>?@[]^_`{|}~
W prawdziwym świecie nadal używamy oryginalnego i najgorszego Netscape cookie_spec, więc kod, który zużywa pliki cookie, powinien być przygotowany na prawie wszystko, ale w przypadku kodu, który wytwarza pliki cookie, zaleca się pozostawanie przy podzbiorze w RFC 6265.
;
znak, dopóki są otoczone podwójnymi cudzysłowami? Jako taki:Set-Cookie: Name=Va";"lue; Max-Age=3600
Name="Va;lue"; max-age...
. Nie działa w przeglądarkach i jest niedozwolony w RFC 6265, który proponuje się zastąpić 2965 i próbuje nieco lepiej odzwierciedlić rzeczywistość.1*<any CHAR except CTLs or separators>
i separatory są(
,)
,<
,>
,@
,,
,;
,:
,\
,"
,/
,[
,]
,?
,=
,{
,}
,SP
iHT
, więc nazwy plików cookie powinny być alphanums Plus!#$%&'*+-.?^_`|~
W ASP.Net można
System.Web.HttpUtility
bezpiecznie zakodować wartość pliku cookie przed zapisaniem go i przekonwertować go z powrotem do oryginalnej postaci po odczytaniu.To zatrzyma znaki handlowe i równe znakom dzielącym wartość na wiązkę par nazwa / wartość, gdy jest zapisywana w pliku cookie.
źródło
Myślę, że ogólnie jest to specyficzne dla przeglądarki. Aby być bezpiecznym, base64 koduje obiekt JSON i zapisuje w nim wszystko. W ten sposób wystarczy go zdekodować i przeanalizować JSON. Wszystkie znaki używane w base64 powinny grać dobrze w większości, jeśli nie we wszystkich przeglądarkach.
źródło
Oto, w jak najkrótszych słowach . Skoncentruj się na postaciach, które nie potrzebują ucieczki:
Tak odpowiadasz.
W przypadku adresów URL zachowano =. Skrzyżowanie jest oczywiście bez.
Okazuje się, że ucieczka wciąż występuje i nieoczekiwane zdarzenie, szczególnie w środowisku plików cookie Java, w którym plik cookie jest zawijany podwójnymi cudzysłowami, jeśli napotka ostatnie znaki.
Aby być bezpiecznym, wystarczy użyć A-Za-z1-9. To właśnie zamierzam zrobić.
źródło
Nowszy rfc6265 opublikowany w kwietniu 2011 r .:
Jeśli spojrzysz na @bobince , zobaczysz, że nowsze ograniczenia są bardziej surowe.
źródło
nie możesz wstawić „;” w polu wartości pliku cookie nazwą, która zostanie ustawiona, jest ciąg znaków do „;” w większości przeglądarek ...
źródło
Istnieją 2 wersje specyfikacji plików cookie
1. Pliki cookie w wersji 0, czyli ciasteczka Netscape,
2. Pliki cookie, w wersji 1 RFC 2965
W wersji 0 Nazwa i wartość ciasteczek to ciągi znaków, z wyłączeniem średnika, przecinka, znaku równości i białych znaków , jeśli nie jest używana z podwójnymi cudzysłowami,
wersja 1 jest o wiele bardziej skomplikowana, możesz to sprawdzić tutaj
W tej wersji specyfikacja części nazwy wartości jest prawie taka sama, z tym że nazwa nie może zaczynać się od znaku $
źródło
Jest jeszcze jeden interesujący problem z IE i Edge. Pliki cookie o nazwach dłuższych niż 1 okres wydają się po cichu usuwane. To działa:
podczas gdy to zostanie porzucone
źródło
to proste:
Link: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Directives
źródło
Jeszcze jedna uwaga. Niedawno wdrożyłem schemat, w którym niektóre wrażliwe dane wysłane do skryptu PHP musiały zostać przekonwertowane i zwrócone jako zaszyfrowane ciasteczko, które wykorzystywało wszystkie wartości base64, które moim zdaniem były gwarantowane jako „bezpieczne”. Więc posłusznie zaszyfrowałem elementy danych za pomocą RC4, uruchomiłem dane wyjściowe za pomocą base64_encode i szczęśliwie zwróciły plik cookie na stronę. Testowanie wydawało się przebiegać dobrze, dopóki ciąg zakodowany w standardzie base64 nie zawierał symbolu „+”. Ciąg został zapisany w pliku cookie strony bez żadnych problemów. Korzystając z diagnostyki przeglądarki, mogłem również sprawdź, czy pliki cookie zostały zapisane bez zmian, a następnie, gdy kolejna strona o nazwie mój PHP i uzyskała plik cookie za pomocą tablicy $ _COOKIE, wyjąkałem, że w łańcuchu brakuje teraz znaku „+”. Każde wystąpienie tego znaku zostało zastąpione znakiem Przestrzeń ASCII.
Biorąc pod uwagę, jak wiele podobnych nierozwiązanych skarg przeczytałem opisujących ten scenariusz od tamtej pory, często umieszczając liczne odniesienia do korzystania z base64 do „bezpiecznego” przechowywania dowolnych danych w plikach cookie, pomyślałem, że zwrócę uwagę na problem i zaoferuję moje niechlujne rozwiązanie.
Po wykonaniu dowolnego szyfrowania na kawałku danych, a następnie użyciu base64_encode, aby uczynić go „bezpiecznym dla plików cookie”, uruchom ciąg wyjściowy przez to ...
Tutaj po prostu podstawiam „+” (i zdecydowałem również „=”) innymi znakami „bezpiecznymi dla plików cookie”, zanim zwrócę zakodowaną wartość na stronę, do wykorzystania jako plik cookie. Zauważ, że długość przetwarzanego ciągu nie zmienia się. Kiedy ta sama (lub inna strona w witrynie) ponownie uruchomi mój skrypt PHP, będę mógł odzyskać ten plik cookie bez brakujących znaków. Muszę tylko pamiętać, aby przekazać plik cookie z powrotem przez to samo wywołanie fix64 (), które utworzyłem, i stamtąd mogę go zdekodować za pomocą zwykłego base64_decode (), a następnie dowolne inne odszyfrowanie w twoim schemacie.
W PHP może istnieć pewne ustawienie, które pozwala na przesyłanie ciągów base64 używanych w plikach cookie z powrotem do PHP bez uszkodzenia. Tymczasem to działa. „+” Może być „legalną” wartością pliku cookie, ale jeśli masz ochotę móc przesłać taki ciąg znaków z powrotem do PHP (w moim przypadku za pomocą tablicy $ _COOKIE), sugeruję ponowne przetworzenie w celu usunięcia obrażające postacie i przywracaj je po odzyskaniu. Do wyboru jest wiele innych znaków „bezpiecznych dla plików cookie”.
źródło
Jeśli później użyjesz zmiennych, przekonasz się, że takie rzeczy jak
path
przepuszczają znaki akcentowane, ale tak naprawdę nie pasują do ścieżki przeglądarki. W tym celu musisz je URIEncode. Czyli tak:Tak więc „dozwolone” znaki mogą być czymś więcej niż zawartym w specyfikacji. Ale powinieneś pozostać w specyfikacji i używać łańcuchów zakodowanych w URI, aby być bezpiecznym.
źródło
Wiele lat temu MSIE 5 lub 5.5 (i prawdopodobnie oba) miały poważny problem z „-” w bloku HTML, jeśli możesz w to uwierzyć. Chociaż nie jest to bezpośrednio powiązane, odkąd przechowujemy skrót MD5 (zawierający tylko litery i cyfry) w pliku cookie, aby wyszukać wszystko inne w bazie danych po stronie serwera.
źródło
Skończyło się na tym
i
Wydaje się, że działa to na wszystkie postacie. Poza tym miałem dziwne problemy, nawet z postaciami, które nie były średnikami ani przecinkami.
źródło