แรงจูงใจเบื้องหลังการแนะนำคำขอ 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การร้องขอรวมทั้งที่ไม่ปลอดภัย ตามข้อกำหนดที่ระบุไว้ : "ทรัพยากรที่คำของ่ายมีความสำคัญนอกเหนือจากการดึงข้อมูลต้องป้องกันตนเองจากการปลอมแปลงคำขอข้ามไซต์"