ทำไมส่วนหัว Set-Cookie ตั้งค่าสำเร็จแต่เบราว์เซอร์ไม่บันทึก Cookie ของฉัน?
นี่คือปัญหาที่พบบ่อยที่สุด เบราว์เซอร์จะไม่รายงานข้อผิดพลาดอย่างแข็งขัน แต่จะทิ้ง Cookie ที่ไม่ปฏิบัติตามข้อกำหนดอย่างเงียบๆ สาเหตุทั่วไป ได้แก่: SameSite=None ขาด Secure, Cookie Secure ถูกตั้งค่าบนหน้า HTTP (ยกเว้น localhost), คำนำหน้า __Host-/__Secure- ไม่เป็นไปตามข้อจำกัด, Domain/Path ไม่ตรงกัน, เกินขีดจำกัดขนาด 4KB, Max-Age เป็นศูนย์หรือค่าลบ แนะนำให้วาง Set-Cookie ลงในเครื่องมือนี้ก่อน ดูเข็มเครื่องหมายเตือนเพื่อระบุสาเหตุเฉพาะ จากนั้นเปิด Chrome DevTools → Application → Cookies ดูภายใต้โดเมนที่เกี่ยวข้องว่ามีสามเหลี่ยมเตือนสีเหลืองหรือไม่ วางเมาส์สามารถเห็นเหตุผลการปฏิเสธเฉพาะ
ความแตกต่างที่แท้จริงระหว่าง Strict, Lax, None ของ SameSite คืออะไร? ควรใช้อันไหนเมื่อไหร่?
Strict ไม่อนุญาตให้ส่งข้ามไซต์อย่างสมบูรณ์ ปลอดภัยที่สุดแต่ผู้ใช้ที่คลิกจากลิงก์ภายนอกจะแสดงว่าไม่ได้เข้าสู่ระบบ เหมาะสำหรับ Cookie ของการดำเนินการที่ละเอียดอ่อนเช่น การชำระเงิน/เปลี่ยนรหัสผ่าน Lax เป็นค่าเริ่มต้นของ Chrome 80+ อนุญาตให้นำไปด้วยเมื่อนำทางกลับผ่านการนำทาง GET ระดับบนสุด (คลิกลิงก์ภายนอกกลับไปยังเว็บไซต์ของคุณ) แต่จะไม่นำไปในทรัพยากรย่อยเช่น iframe/img/script/XHR/ฟอร์ม POST เป็นค่าที่แนะนำสำหรับสถานการณ์ส่วนใหญ่ None อนุญาตให้ส่งในทุกสถานการณ์ข้ามไซต์ (ใช้สำหรับการเข้าสู่ระบบครั้งเดียว SSO, iframe ฝังบุคคลที่สาม, การเรียก API ข้ามไซต์) แต่ต้องตั้งค่า Secure พร้อมกัน มิฉะนั้นเบราว์เซอร์จะปฏิเสธโดยตรง
ทำไม SameSite=None จึงต้องจับคู่กับ Secure?
นี่คือกฎที่ Chrome บังคับใช้ตั้งแต่เวอร์ชัน 80 (กุมภาพันธ์ 2020) Firefox, Edge, Safari ก็ปฏิบัติตามเช่นกัน เนื่องจาก SameSite=None อนุญาตให้ส่ง Cookie ข้ามไซต์อย่างชัดเจน ผู้โจมตีจึงทำการโจมตี CSRF หรือดักฟังได้ง่ายขึ้นในสถานการณ์ข้ามไซต์ จึงต้องจับคู่กับ Secure (การส่งผ่านที่เข้ารหัส HTTPS) เพื่อลดความเสี่ยง หาก Cookie SameSite=None ของคุณถูกตั้งค่าภายใต้ HTTP เบราว์เซอร์จะทิ้งมันโดยตรงโดยไม่บันทึก เครื่องมือนี้จะตรวจจับชุดค่าผสม SameSite=None ขาด Secure และเตือนด้วยสีแดง
ใช้ Max-Age หรือ Expires? ความแตกต่างคืออะไร?
ให้ความสำคัญกับการใช้ Max-Age Max-Age เป็นเวลาสัมพัทธ์ (หมดอายุหลังจากกี่วินาที) ไม่ขึ้นอยู่กับนาฬิกาไคลเอ็นต์ เบราว์เซอร์จะเริ่มนับถอยหลังหลังจากได้รับ; Expires เป็นจุดเวลาสัมบูรณ์ ขึ้นอยู่กับเวลาท้องถิ่นของคอมพิวเตอร์ผู้ใช้ (ผู้ใช้เปลี่ยนนาฬิกาเป็น 1970 Cookie จะหมดอายุทันที) เมื่อทั้งสองมีอยู่พร้อมกัน Max-Age มีความสำคัญเหนือกว่า (RFC 6265 กำหนดอย่างชัดเจน) หากไม่ได้ตั้งค่าทั้งสอง Cookie จะกลายเป็น「Cookie เซสชัน」หมดอายุเมื่อเบราว์เซอร์ปิด เครื่องมือนี้จะให้คำแนะนำสำหรับกรณีที่ตั้งค่า Expires แต่ไม่ได้ตั้งค่า Max-Age แนะนำให้เพิ่ม Max-Age โปรดทราบว่าหน่วยของ Max-Age คือวินาทีไม่ใช่มิลลิวินาที
ความแตกต่างระหว่าง Path=/ และการไม่ตั้งค่า Path คืออะไร?
Path กำหนดว่าเบราว์เซอร์จะนำ Cookie นี้ไปด้วยในคำขอของเส้นทาง URL ใด เมื่อไม่ได้ตั้งค่า Path เบราว์เซอร์จะใช้「เส้นทางหลังจากลบส่วนสุดท้ายของ URL การตอบกลับ」ตามค่าเริ่มต้น ตัวอย่างเช่น ตั้งค่า Cookie จาก /api/user/login Path เริ่มต้นคือ /api/user/ ดังนั้นคำขอภายใต้เส้นทาง / และ /order/ จะไม่นำ Cookie นี้ไปด้วย การตั้งค่า Path=/ อย่างชัดเจนสามารถทำให้ Cookie มีผลกับทั้งไซต์ โปรดทราบว่าการจับคู่ Path คือการจับคู่คำนำหน้า Path=/api จะจับคู่กับ /api/, /api/user, /api/v2/abc ฯลฯ ด้วย Cookie คำนำหน้า __Host- บังคับกำหนดให้ต้องมี Path=/
ความแตกต่างระหว่าง Domain ที่เริ่มต้นด้วยจุด (เช่น .example.com) และไม่มีจุดคืออะไร?
ในเบราว์เซอร์สมัยใหม่ (เวอร์ชันล่าสุดของ Chrome, Firefox, Edge, Safari) ทั้งสองมีค่าเท่ากันแล้ว ทั้งสองจะทำให้ Cookie มีผลกับ example.com และโดเมนย่อยทั้งหมด (a.example.com, b.c.example.com) จุดที่จุดเริ่มต้นเป็นวิธีการเขียนเก่าจากยุค RFC 2109 RFC 6265 ได้กำหนดอย่างชัดเจนให้ละเลยจุดนำหน้า อย่างไรก็ตาม เพื่อความสามารถในการอ่าน แนะนำให้เขียนในรูปแบบที่ไม่มีจุด เครื่องมือนี้จะให้คำแนะนำสำหรับกรณีที่ Domain มีจุดนำหน้า (ไม่ใช่ข้อผิดพลาด แต่เป็นวิธีการเขียนที่เป็นมรดกทางประวัติศาสตร์) โปรดทราบ: เมื่อไม่ได้ตั้งค่า Domain Cookie จะมีผลเฉพาะกับโฮสต์ปัจจุบัน (โดเมนย่อยจะไม่นำไป) หลังจากตั้งค่า Domain จะมีผลกับโดเมนย่อย
คำนำหน้า __Host- และ __Secure- คืออะไร? สามารถไม่เขียนคำนำหน้าได้หรือไม่?
นี่คือคำนำหน้าความปลอดภัยของชื่อ Cookie ที่แนะนำโดย RFC 6265bis ใช้เพื่อเพิ่มข้อจำกัดที่เข้มงวดให้กับ Cookie ความปลอดภัยสูง: เมื่อเบราว์เซอร์เห็นว่าชื่อ Cookie เริ่มต้นด้วย __Host- จะบังคับให้ต้องตั้งค่า Secure, Path=/, ไม่อนุญาตให้ตั้งค่า Domain หากเงื่อนไขใดเงื่อนไขหนึ่งไม่เป็นไปตามข้อกำหนดจะปฏิเสธการจัดเก็บโดยตรง; คำนำหน้า __Secure- กำหนดว่าต้องตั้งค่า Secure คุณสมบัติอื่นสามารถกำหนดค่าได้ การไม่เขียนคำนำหน้าก็สามารถทำงานได้ (Cookie ส่วนใหญ่ไม่ได้ใช้คำนำหน้า) แต่สำหรับ Cookie ความปลอดภัยสูงเช่น ตัวระบุเซสชัน, Token การอนุญาต แนะนำอย่างยิ่งให้ใช้คำนำหน้า __Host- เนื่องจากสามารถป้องกันการโจมตีฉีด Cookie ในระดับโดเมนย่อย/เส้นทาง เครื่องมือนี้จะตรวจสอบการปฏิบัติตามข้อกำหนดของคำนำหน้าทั้งสองประเภทโดยอัตโนมัติ
HttpOnly Cookie ปลอดภัยจริงหรือ? ป้องกัน XSS และ CSRF ได้หรือไม่?
HttpOnly สามารถป้องกัน JavaScript ไม่ให้อ่านค่า Cookie ผ่าน document.cookie เป็นเส้นป้องกันที่สำคัญสำหรับ<strong>ลดการขโมยเซสชัน XSS</strong> แต่ไม่ใช่ยาวิเศษ: ผู้โจมตี XSS ยังสามารถส่งคำขอ (คำขอจะนำ Cookie ไปโดยอัตโนมัติ) ในเบราว์เซอร์ของผู้ใช้เพื่อดำเนินการ (นี่คือขอบเขตของ CSRF); HttpOnly ก็ไม่สามารถป้องกันการโจมตี CSRF ได้ (ต้องใช้ SameSite หรือ CSRF Token ร่วมกัน) เฉพาะเมื่อใช้สามอย่าง HttpOnly+Secure+SameSite=Lax/Strict พร้อมกันจึงจะถึงระดับความปลอดภัยพื้นฐาน Cookie ที่ละเอียดอ่อน (session, JWT, access_token) ต้องเป็น HttpOnly หากไม่จำเป็นอย่าให้ JS ฟรอนต์เอนด์อ่าน เครื่องมือนี้จะเตือน Cookie ที่ขาด HttpOnly
Partitioned (CHIPS) Cookie คืออะไร? เมื่อไหร่จึงควรใช้?
Partitioned เป็นคุณสมบัติใหม่ที่ Chrome แนะนำเพื่อรองรับการยกเลิก Cookie บุคคลที่สาม ชื่อเต็มคือ Cookies Having Independent Partitioned State (CHIPS) Cookie บุคคลที่สามแบบดั้งเดิม (ตัวอย่างเช่น Cookie ที่ตั้งค่าโดยบริการโฆษณา/ฝังบนหลายไซต์) ถูกแชร์ทั่วโลก จะถูกใช้เพื่อติดตามผู้ใช้ข้ามไซต์ หลังจากเพิ่ม Partitioned เบราว์เซอร์จะจัดเก็บ Cookie บุคคลที่สามนั้นแยกกันตามไซต์ระดับบนสุด: Cookie บุคคลที่สามที่ผู้ใช้เห็นบนไซต์ A และไซต์ B แยกจากกันอย่างสมบูรณ์ ไม่สามารถแชร์ข้อมูลระบุตัวตนข้ามไซต์ได้ สถานการณ์การใช้งาน: ส่วนประกอบวิดีโอ/แผนที่/การชำระเงินที่ฝัง, ปลั๊กอินบริการลูกค้าบุคคลที่สาม, iframe SSO ข้ามไซต์ที่ฝัง การใช้ Partitioned ต้องตั้งค่า Secure พร้อมกัน แนะนำให้ใช้ร่วมกับคำนำหน้า __Host-
Cookie หนึ่งรายการสามารถเก็บข้อมูลได้สูงสุดเท่าไหร่? สามารถวางได้กี่รายการต่อโดเมน?
ตาม RFC 6265 เบราว์เซอร์รองรับอย่างน้อย 4096 ไบต์ต่อ Cookie (รวมชื่อ ค่า และคุณสมบัติ) เบราว์เซอร์หลัก (Chrome/Firefox/Safari/Edge) ทั้งหมดปฏิบัติตามขีดจำกัดนี้ ส่วนที่เกินจะถูกตัดทอนหรือทิ้งอย่างเงียบๆ ขีดจำกัดจำนวนแตกต่างกันไปตามเบราว์เซอร์: Chrome ประมาณ 180 ต่อโดเมน, Firefox ประมาณ 150, Safari ประมาณ 600 (และได้รับผลกระทบจากนโยบายล้างข้อมูลเจ็ดวันของ ITP) หลังจากเกินเบราว์เซอร์จะกำจัด Cookie ที่เก่าที่สุดตามกลยุทธ์ LRU แนะนำให้ Cookie เก็บเฉพาะตัวระบุเซสชัน อย่าใส่ข้อมูลธุรกิจขนาดใหญ่ลงใน Cookie (ข้อมูลธุรกิจใส่ใน localStorage หรือ Session ของเซิร์ฟเวอร์)
รองรับการคัดลอก Set-Cookie โดยตรงจาก Chrome DevTools เพื่อแยกวิเคราะห์หรือไม่? จำเป็นต้องลบคำนำหน้าด้วยตนเองหรือไม่?
รองรับอย่างสมบูรณ์ ไม่จำเป็นต้องประมวลผลด้วยตนเอง คุณสามารถใน Chrome DevTools → แผง Network คลิกคำขอเป้าหมาย คัดลอกค่า Set-Cookie โดยตรงโดยคลิกขวาในพื้นที่ Response Headers (เมื่อมีหลายบรรทัด กด Ctrl/⌘+คลิกเพื่อเลือกหลายรายการหรือคัดลอกทั้งหมด) วางลงในพื้นที่ป้อนข้อมูลของเครื่องมือนี้ก็เพียงพอแล้ว เครื่องมือจะลบคำนำหน้า Set-Cookie: ที่จุดเริ่มต้นของแต่ละบรรทัดโดยอัตโนมัติ (ไม่คำนึงถึงตัวพิมพ์ใหญ่-เล็ก) ประมวลผลช่องว่างที่จุดเริ่มต้นและท้ายบรรทัดโดยอัตโนมัติ จัดการอักขระพิเศษเช่น จุลภาค อัฒภาคที่อยู่ในวันที่ Expires อย่างถูกต้อง และยังสามารถจัดการค่า Cookie ที่มีเครื่องหมายคำพูดคู่ได้อย่างถูกต้อง
ทำไมอักขระที่ไม่ใช่ ASCII หรืออักขระพิเศษในค่า Cookie จึงกลายเป็นรูปแบบ %XX?
RFC 6265 กำหนดว่าค่า Cookie สามารถใช้ได้เฉพาะชุดย่อยที่ปลอดภัยในชุดอักขระ ASCII เท่านั้น ไม่สามารถมีอักขระที่ไม่ใช่ ASCII ช่องว่าง จุลภาค อัฒภาค ฯลฯ ได้โดยตรง เฟรมเวิร์กฝั่งเซิร์ฟเวอร์จำนวนมากเมื่อตั้งค่า Cookie จะทำการเข้ารหัส URL (encodeURIComponent/Percent-encoding) สำหรับอักขระที่ไม่ใช่ ASCII โดยอัตโนมัติ ตัวอย่างเช่น ข้อความภาษาไทยจะถูกเข้ารหัสเป็นรูปแบบ %XX เบราว์เซอร์ก็จะรักษารูปแบบการเข้ารหัสไว้เมื่อส่งกลับ เมื่อเครื่องมือนี้ตรวจพบว่าค่ามีการเข้ารหัส %XX จะแสดงข้อความดั้งเดิมหลังถอดรหัส decodeURIComponent โดยอัตโนมัติด้วยลูกศรสีเขียวข้างๆ ค่าดั้งเดิม เพื่อให้คุณดูเนื้อหาจริงได้อย่างสะดวก
ความแตกต่างระหว่าง Set-Cookie และส่วนหัวคำขอ Cookie คืออะไร?
ส่วนหัวทั้งสองมีทิศทางที่แตกต่างกันอย่างสมบูรณ์: Set-Cookie คือส่วนหัวตอบกลับ (เซิร์ฟเวอร์ → เบราว์เซอร์) ปรากฏเฉพาะในการตอบกลับ สามารถปรากฏได้หลายครั้ง แต่ละครั้งตั้งค่า Cookie หนึ่งรายการ มีคุณสมบัติที่สมบูรณ์ (Secure/HttpOnly/Path/Domain ฯลฯ); Cookie คือส่วนหัวคำขอ (เบราว์เซอร์ → เซิร์ฟเวอร์) แต่ละคำขอจะปรากฏเพียงครั้งเดียว ภายในเป็นคู่ name=value แบนราบของ Cookie ทั้งหมดที่ตรงกับขอบเขตในปัจจุบัน (name1=v1; name2=v2) ไม่มีข้อมูลคุณสมบัติใดๆ เลย กล่าวคือ เซิร์ฟเวอร์ไม่สามารถทราบจากคำขอว่า Cookie ใดได้ตั้งค่า HttpOnly หรือ Secure หรือไม่ ข้อมูลคุณสมบัติจะถูกเก็บไว้ในเครื่องโดยเบราว์เซอร์เท่านั้น หากต้องการแยกวิเคราะห์ส่วนหัวคำขอ Cookie โปรดใช้<a href='/network/http-cookie-parser/'>ตัวแยกวิเคราะห์ส่วนหัวคำขอ Cookie</a>ที่มาพร้อมกัน
ทำไม Cookie ของฉันใน Safari จึงหายไปหลังจากผ่านไปสองสามวัน?
นี่คือกลไกการป้องกันการติดตามอัจฉริยะ (ITP: Intelligent Tracking Prevention) ของ Safari ที่ทำงาน ตั้งแต่ ITP 2.1 เป็นต้นไป หากผู้ใช้ไม่ได้โต้ตอบโดยตรงกับโดเมนนั้นภายใน 7 วัน (คือไม่ได้เข้าชมเว็บไซต์ของโดเมนนั้นโดยตรง) Safari จะล้าง Cookie และข้อมูลไซต์ทั้งหมดภายใต้โดเมนนั้น ไม่ว่า Max-Age/Expires จะตั้งค่าไว้นานเท่าใด สิ่งนี้ส่งผลกระทบมากที่สุดต่อบริการฝังบุคคลที่สาม สำหรับ Cookie ของไซต์หลักจะไม่ได้รับผลกระทบเมื่อผู้ใช้เข้าชมอย่างต่อเนื่อง นอกจากนี้ Safari ยังจำกัด Cookie บุคคลที่สามที่เข้มงวดกว่า Chrome อีกด้วย วิธีแก้ไข ได้แก่: ใช้คุณสมบัติ Partitioned, ขอสิทธิ์ผ่าน Storage Access API, หรือรีเฟรช Cookie ใหม่เมื่อผู้ใช้เข้าชมไซต์หลัก บทแก้ไขปัญหาของเครื่องมือนี้มีคำแนะนำการดีบัก Safari ที่ละเอียดมากขึ้น
เครื่องมือรองรับการแยกวิเคราะห์ Set-Cookie จำนวนมากหรือไม่? จะอัปโหลดเนื้อหา Cookie ไปยังเซิร์ฟเวอร์หรือไม่?
รองรับการแยกวิเคราะห์จำนวนมาก พื้นที่ป้อนข้อมูลรองรับการวาง Set-Cookie หลายบรรทัดตามจำนวนที่ต้องการ (ตัวอย่างเช่น วางส่วนหัวตอบกลับทั้งหมดในครั้งเดียว) แต่ละ Set-Cookie จะถูกแยกวิเคราะห์ด้วยหมายเลขลำดับอิสระ การ์ดคุณสมบัติหลายใบแสดงคุณสมบัติและคำเตือนของแต่ละรายการแยกกัน กระบวนการแยกวิเคราะห์ทั้งหมดเสร็จสิ้นในเครื่องในเบราว์เซอร์ของคุณ (ประมวลผลด้วย JavaScript ฟรอนต์เอนด์ล้วนๆ) เนื้อหา Cookie จะไม่ถูกอัปโหลดไปยังเซิร์ฟเวอร์ใดๆ และจะไม่ส่งคำขอเครือข่ายใดๆ ข้อมูลที่ละเอียดอ่อนเช่น Session/Token ที่คุณวางจะไม่ออกจากคอมพิวเตอร์ของคุณ สามารถใช้งานได้อย่างมั่นใจ