แรงจูงใจเบื้องหลังการแนะนำคำขอ preflight คืออะไร
มีการแนะนำคำขอ preflight เพื่อให้เบราว์เซอร์แน่ใจได้ว่าจัดการกับเซิร์ฟเวอร์ CORS-aware ก่อนที่จะส่งคำขอบางอย่าง คำขอเหล่านั้นถูกกำหนดให้เป็นคำขอที่อาจเป็นอันตราย (เปลี่ยนสถานะ) และใหม่ (ไม่สามารถทำได้ก่อน CORS เนื่องจากนโยบายแหล่งกำเนิดเดียวกัน ) การใช้คำขอ preflight หมายความว่าเซิร์ฟเวอร์จะต้องเลือกใช้ (โดยตอบสนองอย่างถูกต้องกับ preflight) กับคำขอประเภทใหม่ที่อาจเป็นอันตรายซึ่ง CORS ทำให้เป็นไปได้
นั่นคือความหมายของส่วนหนึ่งของข้อมูลจำเพาะ : "เพื่อปกป้องทรัพยากรจากการร้องขอข้ามแหล่งที่ไม่สามารถเกิดจากตัวแทนผู้ใช้บางรายก่อนที่ข้อกำหนดนี้จะมีการร้องขอ preflight ถูกสร้างขึ้นเพื่อให้แน่ใจว่าทรัพยากรตระหนักถึงข้อกำหนดนี้"
คุณยกตัวอย่างให้ฉันได้ไหม
A.com
ลองจินตนาการว่าผู้ใช้เบราว์เซอร์จะเข้าสู่เว็บไซต์ธนาคารของพวกเขาที่ เมื่อพวกเขาไปที่ที่เป็นอันตรายB.com
, หน้าที่มี Javascript บางอย่างที่พยายามที่จะส่งคำขอไปยังDELETE
A.com/account
เนื่องจากผู้ใช้เข้าสู่ระบบA.com
คำขอนั้นถ้าส่งจะรวมถึงคุกกี้ที่ระบุผู้ใช้
ก่อน CORS นโยบายแหล่งกำเนิดเดียวกันของเบราว์เซอร์จะบล็อกไม่ให้ส่งคำขอนี้ แต่เนื่องจากจุดประสงค์ของ CORS คือการทำให้การสื่อสารข้ามจุดประสงค์นี้เป็นไปได้จึงไม่เหมาะสมอีกต่อไป
เบราว์เซอร์สามารถส่งDELETE
และแจ้งให้เซิร์ฟเวอร์ตัดสินใจว่าจะจัดการกับมันอย่างไร แต่ถ้าหากA.com
ไม่รู้เกี่ยวกับโปรโตคอล CORS ล่ะ DELETE
มันอาจจะไปข้างหน้าและดำเนินการที่เป็นอันตราย อาจสันนิษฐานว่า - เนื่องจากนโยบายกำเนิดเดียวกันของเบราว์เซอร์ - ไม่สามารถรับคำขอดังกล่าวได้และดังนั้นจึงอาจไม่เคยถูกต่อต้านจากการโจมตีดังกล่าว
เพื่อปกป้องเซิร์ฟเวอร์ที่ไม่ทราบ CORS ดังนั้นโปรโตคอลจะต้องให้เบราว์เซอร์ส่งคำขอ preflightก่อน คำขอชนิดใหม่นี้เป็นสิ่งที่เซิร์ฟเวอร์ที่รับรู้ถึง CORS เท่านั้นที่สามารถตอบสนองได้อย่างถูกต้องทำให้เบราว์เซอร์ทราบว่าปลอดภัยที่จะส่งจริงDELETE
หรือไม่
เหตุใดเรื่องทั้งหมดนี้เกี่ยวกับเบราว์เซอร์ผู้โจมตีเพียงแค่ส่งDELETE
คำขอจากคอมพิวเตอร์ของตนเองไม่ได้?
แน่นอน แต่คำขอดังกล่าวจะไม่รวมคุกกี้ของผู้ใช้ การโจมตีที่ถูกออกแบบมาเพื่อป้องกันนั้นขึ้นอยู่กับข้อเท็จจริงที่ว่าเบราว์เซอร์จะส่งคุกกี้ (โดยเฉพาะข้อมูลการตรวจสอบสิทธิ์สำหรับผู้ใช้) สำหรับโดเมนอื่นพร้อมกับคำขอ
เสียงที่เหมือนข้ามไซต์ปลอมขอที่แบบฟอร์มในเว็บไซต์B.com
สามารถPOST
ไปA.com
กับคุกกี้ของผู้ใช้และจะเกิดความเสียหาย
ถูกตัอง. อีกวิธีหนึ่งในการทำเช่นนี้คือคำขอ preflight ถูกสร้างขึ้นเพื่อไม่เพิ่มพื้นผิวการโจมตี CSRF สำหรับเซิร์ฟเวอร์ที่ไม่ทราบ CORS
แต่เมื่อดูข้อกำหนดสำหรับคำขอ "เรียบง่าย" ที่ไม่ต้องใช้ไฟลต์ฉันเห็นว่าPOST
ยังคงได้รับอนุญาต ที่สามารถเปลี่ยนสถานะและลบข้อมูลได้เหมือนDELETE
!
นั่นเป็นความจริง! CORS ไม่ปกป้องไซต์ของคุณจากการโจมตี CSRF จากนั้นอีกครั้งหากไม่มี CORS คุณจะไม่ได้รับการปกป้องจากการโจมตี CSRF วัตถุประสงค์ของคำขอ preflight คือเพื่อ จำกัด การเปิดเผย CSRF ของคุณกับสิ่งที่มีอยู่แล้วในโลกก่อนยุค
ถอนหายใจ ตกลงฉันไม่เต็มใจยอมรับความต้องการคำขอ preflight แต่ทำไมเราต้องทำกับทุก ๆ ทรัพยากร (URL) บนเซิร์ฟเวอร์? เซิร์ฟเวอร์จัดการกับ CORS ไม่เช่นนั้น
คุณแน่ใจเหรอ ไม่ใช่เรื่องแปลกที่เซิร์ฟเวอร์หลายเครื่องจะจัดการคำขอสำหรับโดเมนเดียว ตัวอย่างเช่นอาจเป็นกรณีที่การร้องขอA.com/url1
ถูกจัดการโดยเซิร์ฟเวอร์ชนิดหนึ่งและการร้องขอที่A.com/url2
จัดการโดยเซิร์ฟเวอร์ประเภทอื่น ไม่ใช่กรณีที่เซิร์ฟเวอร์ที่จัดการทรัพยากรเดียวสามารถรับประกันความปลอดภัยเกี่ยวกับทรัพยากรทั้งหมดในโดเมนนั้น
ละเอียด. มาประนีประนอมกัน มาสร้างส่วนหัว CORS ใหม่ที่อนุญาตให้เซิร์ฟเวอร์ระบุทรัพยากรที่สามารถพูดได้อย่างแม่นยำเพื่อที่จะหลีกเลี่ยงคำขอ preflight เพิ่มเติมไปยัง URL เหล่านั้น
ความคิดที่ดี! ในความเป็นจริงส่วนหัวAccess-Control-Policy-Path
ถูกเสนอเพื่อวัตถุประสงค์นี้เท่านั้น ในที่สุดแม้ว่ามันจะถูกปล่อยออกมาจากสเปคเห็นได้ชัดเพราะบางเซิร์ฟเวอร์ดำเนินเปค URI ในทางที่ไม่ถูกต้องดังกล่าวว่าการร้องขอไปยังเส้นทางที่ดูเหมือนจะปลอดภัยในการเบราว์เซอร์จะไม่ได้อยู่ในความเป็นจริงจะปลอดภัยบนเซิร์ฟเวอร์ของเสีย
นี่เป็นการตัดสินใจที่รอบคอบที่ให้ความสำคัญด้านความปลอดภัยมากกว่าประสิทธิภาพการอนุญาตให้เบราว์เซอร์ใช้ข้อกำหนดของ CORS ได้ทันทีโดยไม่ต้องเสี่ยงกับเซิร์ฟเวอร์ที่มีอยู่หรือไม่ หรือว่ามันสั้นเกินไปที่จะลงโทษอินเทอร์เน็ตให้เสียแบนด์วิดท์และเพิ่มเวลาแฝงเป็นสองเท่าเพื่อรองรับข้อผิดพลาดในเซิร์ฟเวอร์เฉพาะช่วงเวลาหนึ่ง
ความคิดเห็นที่แตกต่าง
เบราว์เซอร์อย่างน้อยที่สุดจะแคช preflight สำหรับ URL เดียวหรือไม่
ใช่. แม้ว่าอาจจะไม่นานนัก ในเบราว์เซอร์ WebKit เวลาแคช preflight สูงสุดคือ10 นาทีในปัจจุบัน
ถอนหายใจ ถ้าฉันรู้ว่าเซิร์ฟเวอร์ของฉันทราบถึง CORS และดังนั้นจึงไม่ต้องการการปกป้องจากคำขอ preflight มีวิธีใดบ้างที่ฉันจะหลีกเลี่ยงได้
ทางเลือกเดียวที่แท้จริงของคุณคือตรวจสอบให้แน่ใจว่าคุณปฏิบัติตามข้อกำหนดสำหรับคำขอ "เรียบง่าย" นั่นอาจหมายถึงการออกจากส่วนหัวที่กำหนดเองที่คุณจะใส่ (เช่นX-Requested-With
) โกหกเกี่ยวกับContent-Type
หรือมากกว่านั้น
สิ่งที่คุณทำคุณต้องให้แน่ใจว่าคุณมีการป้องกัน CSRF เหมาะสมในสถานที่ตั้งแต่ข้อกำหนดล ธ ไม่อยู่ไม่ได้ปฏิเสธ "ง่าย" POST
การร้องขอรวมทั้งที่ไม่ปลอดภัย ตามข้อกำหนดที่ระบุไว้ : "ทรัพยากรที่คำของ่ายมีความสำคัญนอกเหนือจากการดึงข้อมูลต้องป้องกันตนเองจากการปลอมแปลงคำขอข้ามไซต์"