ini quickie:
Anda mungkin berpikir itu seharusnya, tetapi sebenarnya tidak sama sekali!
Apa saja karakter yang diizinkan dalam nama dan nilai cookie?
Menurut cookie_spec Netscape kuno seluruh NAME=VALUE
string adalah:
urutan karakter tidak termasuk titik koma, koma, dan spasi putih.
Jadi -
seharusnya bekerja, dan sepertinya OK di browser saya sudah sampai di sini; di mana Anda mengalami masalah dengan itu?
Dengan implikasi dari hal di atas:
=
legal untuk dimasukkan, tetapi berpotensi ambigu. Browser selalu membagi nama dan nilai pada =
simbol pertama dalam string, jadi dalam praktiknya Anda dapat menempatkan =
simbol di VALUE tetapi tidak pada NAME.
Apa yang tidak disebutkan, karena Netscape sangat buruk dalam menulis spesifikasi, tetapi tampaknya secara konsisten didukung oleh browser:
NAME atau VALUE mungkin berupa string kosong
jika tidak ada =
simbol dalam string sama sekali, browser memperlakukannya sebagai cookie dengan nama string-kosong, yaitu Set-Cookie: foo
sama dengan Set-Cookie: =foo
.
ketika browser menampilkan cookie dengan nama kosong, mereka menghilangkan tanda sama dengan. Jadi Set-Cookie: =bar
pinta Cookie: bar
.
koma dan spasi dalam nama dan nilai tampaknya benar-benar berfungsi, meskipun ruang di sekitar tanda sama dipangkas
kontrol karakter ( \x00
ke \x1F
plus \x7F
) tidak diizinkan
Yang tidak disebutkan dan peramban yang sepenuhnya tidak konsisten adalah karakter non-ASCII (Unicode):
- di Opera dan Google Chrome, mereka dikodekan ke header Cookie dengan UTF-8;
- di IE, halaman kode default mesin digunakan (khusus lokal dan tidak pernah UTF-8);
- Firefox (dan browser berbasis Mozilla lainnya) menggunakan byte rendah dari masing-masing titik kode UTF-16 sendiri (jadi ISO-8859-1 tidak apa-apa tetapi yang lainnya hancur);
- Safari menolak untuk mengirim cookie apa pun yang mengandung karakter non-ASCII.
jadi dalam praktiknya Anda tidak dapat menggunakan karakter non-ASCII di cookie sama sekali. Jika Anda ingin menggunakan Unicode, kode kontrol atau urutan byte sewenang-wenang lainnya, cookie_spec menuntut Anda menggunakan skema pengkodean ad-hoc yang Anda pilih sendiri dan menyarankan pengkodean URL (seperti yang diproduksi oleh JavaScript encodeURIComponent
) sebagai pilihan yang wajar.
Dalam hal standar aktual , ada beberapa upaya untuk menyusun perilaku cookie, tetapi sejauh ini tidak ada yang benar-benar mencerminkan dunia nyata.
RFC 2109 adalah upaya untuk mengkodifikasi dan memperbaiki cookie_spec Netscape asli. Dalam standar ini banyak karakter khusus lagi yang dianulir, karena menggunakan RFC 2616 token (a -
adalah masih diperbolehkan ada), dan hanya nilai dapat ditentukan dalam dikutip-string dengan karakter lain. Tidak ada browser yang menerapkan batasan, penanganan khusus dari string dan pelarian yang dikutip, atau fitur baru dalam spesifikasi ini.
RFC 2965 lain dalam hal ini, merapikan 2109 dan menambahkan lebih banyak fitur di bawah skema 'cookie versi 2'. Tidak ada yang pernah menerapkan semua itu. Spesifikasi ini memiliki batasan token-dan-dikutip-string yang sama dengan versi sebelumnya dan itu sama banyaknya dengan omong kosong.
RFC 6265 adalah upaya HTML5-era untuk membersihkan kekacauan sejarah. Itu masih tidak cocok dengan kenyataan, tetapi itu jauh lebih baik daripada upaya sebelumnya — itu setidaknya bagian yang tepat dari apa yang didukung browser, tidak memperkenalkan sintaks yang seharusnya berfungsi tetapi tidak (seperti string yang dikutip sebelumnya) .
Di 6265 nama cookie masih ditentukan sebagai RFC 2616 token
, yang berarti Anda dapat memilih dari alfanumer plus:
!#$%&'*+-.^_`|~
Dalam nilai cookie itu secara formal melarang karakter kontrol (difilter oleh browser) dan (non-ASCII karakter) yang diimplementasikan. Ini mempertahankan larangan cookie_spec pada ruang, koma, dan titik koma, ditambah untuk kompatibilitas dengan orang idiot miskin yang benar-benar menerapkan RFC sebelumnya, ia juga melarang backslash dan kutipan, selain dari kutipan yang membungkus seluruh nilai (tetapi dalam hal itu kutipan masih dianggap sebagai bagian dari nilai, bukan skema penyandian). Sehingga meninggalkan Anda dengan alfanumer plus:
!#$%&'()*+-./:<=>?@[]^_`{|}~
Di dunia nyata kita masih menggunakan Netscape cookie_spec asli-dan-terburuk, jadi kode yang mengkonsumsi cookie harus siap menghadapi banyak hal, tetapi untuk kode yang menghasilkan cookie disarankan untuk tetap menggunakan subset di RFC 6265.
;
karakter selama dikelilingi oleh tanda kutip ganda? Dengan demikian:Set-Cookie: Name=Va";"lue; Max-Age=3600
Name="Va;lue"; max-age...
. Itu tidak bekerja di browser dan itu tidak diizinkan di RFC 6265, yang diusulkan untuk menggantikan 2965 dan mencoba untuk mencerminkan kenyataan sedikit lebih baik.1*<any CHAR except CTLs or separators>
dan pemisah yang(
,)
,<
,>
,@
,,
,;
,:
,\
,"
,/
,[
,]
,?
,=
,{
,}
,SP
danHT
, sehingga nama cookie harus alphanums ditambah!#$%&'*+-.?^_`|~
Di ASP.Net, Anda dapat menggunakannya
System.Web.HttpUtility
untuk menyandikan nilai cookie dengan aman sebelum menulis ke cookie dan mengubahnya kembali ke bentuk aslinya saat membacanya.Ini akan menghentikan ampersand dan sama dengan tanda-tanda yang membagi nilai menjadi sekelompok pasangan nama / nilai saat ditulis ke cookie.
sumber
Saya pikir ini umumnya browser spesifik. Untuk berada di sisi aman, base64 menyandikan objek JSON, dan menyimpan segala sesuatu di dalamnya. Dengan begitu Anda hanya perlu men-decode dan mengurai JSON. Semua karakter yang digunakan dalam base64 harus bermain baik dengan sebagian besar, jika tidak semua browser.
sumber
Ini dia, sesedikit mungkin kata-kata . Fokus pada karakter yang tidak perlu melarikan diri:
Itulah jawaban Anda.
Untuk url ini = disimpan. Persimpangan jelas tanpa.
Ternyata melarikan diri masih terjadi dan tidak terduga terjadi, terutama di lingkungan cookie Java di mana cookie dibungkus dengan tanda kutip ganda jika bertemu dengan karakter terakhir.
Jadi agar aman, cukup gunakan A-Za-z1-9. Itu yang akan saya lakukan.
sumber
Rfc6265 yang lebih baru diterbitkan pada bulan April 2011:
Jika Anda melihat jawaban @bobince, Anda melihat bahwa pembatasan yang lebih baru lebih ketat.
sumber
Anda tidak bisa memasukkan ";" di bidang nilai cookie, nama yang akan ditetapkan adalah string hingga ";" di sebagian besar browser ...
sumber
Ada 2 versi spesifikasi cookie
1. Cookie versi 0 alias cookie Netscape,
2. Versi 1 alias cookie RFC 2965
Dalam versi 0 Nama dan nilai cookie adalah urutan karakter, tidak termasuk tanda titik koma, koma, tanda sama dengan, dan spasi putih , jika tidak digunakan dengan tanda kutip ganda
versi 1 jauh lebih rumit, Anda dapat memeriksanya di sini.
Dalam versi ini spesifikasi untuk bagian nilai nama hampir sama kecuali nama tidak dapat dimulai dengan $ tanda
sumber
Ada masalah lain yang menarik dengan IE dan Edge. Cookie yang memiliki nama dengan lebih dari 1 periode nampaknya diam-diam dihapus. Jadi ini berfungsi:
sementara ini akan turun
sumber
itu sederhana:
Tautan: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Directives
sumber
Satu pertimbangan lagi. Saya baru-baru ini menerapkan skema di mana beberapa data sensitif diposting ke skrip PHP perlu untuk mengkonversi dan mengembalikannya sebagai cookie terenkripsi, yang menggunakan semua nilai base64 yang saya pikir dijamin 'aman ". Jadi saya patuh mengenkripsi item data menggunakan RC4, berlari output melalui base64_encode, dan dengan senang hati mengembalikan cookie ke situs. Pengujian tampaknya berjalan dengan baik sampai string base64 yang dikodekan mengandung simbol "+". String ditulis ke cookie halaman tanpa masalah. Menggunakan diagnosa browser saya juga bisa memverifikasi cookie ditulis tidak berubah. Kemudian ketika halaman berikutnya memanggil PHP saya dan memperoleh cookie melalui $ _COOKIE array, saya tergagap untuk menemukan string sekarang hilang tanda "+". Setiap kemunculan karakter itu diganti dengan Ruang ASCII.
Mempertimbangkan berapa banyak keluhan serupa yang belum terselesaikan yang saya baca menggambarkan skenario ini sejak itu, sering mencari berbagai referensi untuk menggunakan base64 untuk "dengan aman" menyimpan data sewenang-wenang dalam cookie, saya pikir saya akan menunjukkan masalahnya dan menawarkan solusi yang saya anggap kumuh.
Setelah Anda melakukan enkripsi apa pun yang ingin Anda lakukan pada sepotong data, dan kemudian menggunakan base64_encode untuk membuatnya "cookie-safe", jalankan string keluaran melalui ini ...
Di sini saya hanya mengganti "+" (dan saya memutuskan "=" juga) dengan karakter "cookie safe" lainnya, sebelum mengembalikan nilai yang disandikan ke halaman, untuk digunakan sebagai cookie. Perhatikan bahwa panjang string yang sedang diproses tidak berubah. Ketika halaman yang sama (atau halaman lain di situs) menjalankan skrip PHP saya lagi, saya akan dapat memulihkan cookie ini tanpa karakter yang hilang. Saya hanya perlu ingat untuk meneruskan cookie kembali melalui panggilan fix64 () yang saya buat, dan dari sana saya dapat mendekode dengan base64_decode () biasa, diikuti oleh dekripsi apa pun lainnya dalam skema Anda.
Mungkin ada beberapa pengaturan yang bisa saya buat di PHP yang memungkinkan string base64 yang digunakan dalam cookie untuk ditransfer kembali ke PHP tanpa korupsi. Sementara itu, ini bekerja. "+" Mungkin nilai cookie "legal", tetapi jika Anda memiliki keinginan untuk dapat mengirimkan string seperti itu kembali ke PHP (dalam kasus saya melalui array $ _COOKIE), saya menyarankan pemrosesan ulang untuk menghapus menyinggung karakter, dan mengembalikannya setelah pemulihan. Ada banyak karakter "cookie aman" lainnya untuk dipilih.
sumber
Jika Anda menggunakan variabel nanti, Anda akan menemukan bahwa hal-hal seperti
path
sebenarnya akan membiarkan karakter beraksen melewatinya, tetapi itu tidak akan benar-benar cocok dengan jalur browser. Untuk itu Anda perlu URIEncode mereka. Jadi seperti ini:Jadi karakter "diizinkan", mungkin lebih dari yang ada di spec. Tetapi Anda harus tetap dalam spesifikasi, dan menggunakan string yang dikodekan-URI agar aman.
sumber
Bertahun-tahun yang lalu, MSIE 5 atau 5.5 (dan mungkin keduanya) memiliki beberapa masalah serius dengan tanda "-" di blok HTML jika Anda percaya. Meskipun ini tidak terkait langsung, sejak kami menyimpan hash MD5 (hanya berisi huruf dan angka) di cookie untuk mencari segala sesuatu yang lain dalam database sisi server.
sumber
Saya akhirnya menggunakan
dan
Itu tampaknya bekerja untuk semua jenis karakter. Sebaliknya, saya memiliki masalah aneh, bahkan dengan karakter yang bukan titik koma atau koma.
sumber