คุกกี้ HttpOnly ทำงานกับคำขอ AJAX อย่างไร


195

JavaScript ต้องการเข้าถึงคุกกี้หากใช้ AJAX บนไซต์ที่มีข้อ จำกัด การเข้าถึงตามคุกกี้ HttpOnly cookies จะทำงานบนไซต์ AJAX หรือไม่

แก้ไข: Microsoft สร้างวิธีในการป้องกันการโจมตี XSS โดยไม่อนุญาตให้เข้าถึง JavaScript กับคุกกี้หากระบุ HttpOnly FireFox นำมาใช้ในภายหลังนี้ ดังนั้นคำถามของฉันคือ: หากคุณใช้ AJAX บนไซต์เช่น StackOverflow คุกกี้ Http-Only เป็นตัวเลือกหรือไม่

แก้ไข 2:คำถามที่ 2 หากวัตถุประสงค์ของ HttpOnly คือป้องกันการเข้าถึง JavaScript ของคุกกี้และคุณยังสามารถเรียกดูคุกกี้ผ่าน JavaScript ผ่าน XmlHttpRequest Object ได้จุดประสงค์ของ HttpOnlyคืออะไร

แก้ไข 3:นี่คือคำพูดจาก Wikipedia:

เมื่อเบราว์เซอร์ได้รับคุกกี้ดังกล่าวก็ควรจะใช้มันตามปกติในการแลกเปลี่ยน HTTP ต่อไปนี้ แต่จะไม่ทำให้สคริปต์ฝั่งไคลเอ็นต์ปรากฏให้เห็น [32] การHttpOnlyตั้งค่าสถานะไม่ได้เป็นส่วนหนึ่งของมาตรฐานใด ๆ และไม่ได้ใช้งานในเบราว์เซอร์ทั้งหมด โปรดทราบว่าขณะนี้ไม่มีการป้องกันการอ่านหรือเขียนคุกกี้เซสชันผ่าน XMLHTTPRequest [33]

ฉันเข้าใจว่าdocument.cookieถูกบล็อกเมื่อคุณใช้ HttpOnly แต่ดูเหมือนว่าคุณยังสามารถอ่านค่าคุกกี้ในวัตถุ XMLHttpRequest ซึ่งอนุญาตให้ใช้ XSS HttpOnly ทำให้คุณปลอดภัยกว่านี้อย่างไร? โดยการทำคุกกี้เป็นหลักอ่านอย่างเดียว?

ในตัวอย่างของคุณฉันไม่สามารถเขียนถึงคุณdocument.cookieแต่ฉันยังสามารถขโมยคุกกี้ของคุณและโพสต์ไปยังโดเมนของฉันโดยใช้วัตถุ XMLHttpRequest

<script type="text/javascript">
    var req = null;
    try { req = new XMLHttpRequest(); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
    req.open('GET', 'http://stackoverflow.com/', false);
    req.send(null);
    alert(req.getAllResponseHeaders());
</script>

แก้ไข 4:ขออภัยฉันหมายความว่าคุณสามารถส่ง XMLHttpRequest ไปยังโดเมน StackOverflow จากนั้นบันทึกผลลัพธ์ของ getAllResponseHeaders () ไปยังสตริงลงทะเบียนคุกกี้แล้วโพสต์นั้นไปยังโดเมนภายนอก ดูเหมือนว่า Wikipedia และ ha.ckers เห็นด้วยกับฉันในเรื่องนี้ แต่ฉันจะรักการศึกษา ...

รอบชิงชนะเลิศแก้ไข:อ่าเห็นได้ชัดว่าเว็บไซต์ทั้งสองมีความผิดนี้เป็นจริงข้อผิดพลาดใน Firefox IE6 & 7 เป็นเบราว์เซอร์ที่สนับสนุน HttpOnly เท่านั้น

เพื่อย้ำทุกสิ่งที่ฉันได้เรียนรู้:

  • HttpOnly จำกัด การเข้าถึง document.cookie ทั้งหมดใน IE7 & และ FireFox (ไม่แน่ใจเกี่ยวกับเบราว์เซอร์อื่น)
  • HttpOnly ลบข้อมูลคุกกี้ออกจากส่วนหัวการตอบสนองใน XMLHttpObject.getAllResponseHeaders () ใน IE7
  • XMLHttpObjects สามารถส่งไปยังโดเมนที่มาจากเท่านั้นดังนั้นจึงไม่มีการโพสต์ข้ามโดเมนของคุกกี้

แก้ไข: ข้อมูลนี้มีแนวโน้มที่จะไม่ทันสมัย


ฉันโยนตัวอย่างของคุณในสคริปต์ greasemonkey และดูเหมือนว่า FF จะไม่แสดงคุกกี้อีกต่อไป การวิจัยและตัวอย่างที่ยอดเยี่ยม

อาจมีนโยบายกำเนิดเดียวกันคุณไม่สามารถส่งคำขอ http ไปยังโดเมนที่ไม่เหมือนกันกับที่สคริปต์กำลังทำงานอยู่ อย่างไรก็ตามฉันเชื่อว่าคุณสามารถผ่านคุกกี้ได้อย่างง่ายดายโดยการเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าเว็บที่ใช้ window.location และส่งข้อมูลผ่านพารามิเตอร์สตริงแบบสอบถาม
Luca Marzi

@LucaMarzi " คุณไม่สามารถส่งคำขอ http ไปยังโดเมนที่ไม่เหมือนกันกับสคริปต์ที่ทำงานใน " คุณกำลังบอกว่าไซต์ X ไม่สามารถรวมภาพจากโฮสต์ Y ได้หรือไม่ (คุณลักษณะที่ได้รับการสนับสนุนจากเบราว์เซอร์ทั้งหมดตั้งแต่ Mosaic?)
curiousguy

คำตอบ:


64

ใช่คุกกี้ HTTP เท่านั้นจะใช้ได้กับฟังก์ชันนี้ พวกเขาจะยังคงได้รับคำขอ XmlHttpRequest ไปยังเซิร์ฟเวอร์

ในกรณีของ Stack Overflow คุกกี้จะได้รับโดยอัตโนมัติเป็นส่วนหนึ่งของคำขอ XmlHttpRequest ฉันไม่ทราบรายละเอียดการใช้งานของผู้ให้บริการการตรวจสอบสิทธิ์ Stack Overflow แต่อาจมีการใช้ข้อมูลคุกกี้เพื่อตรวจสอบข้อมูลประจำตัวของคุณในระดับที่ต่ำกว่าวิธีการควบคุม "โหวต" โดยอัตโนมัติ

โดยทั่วไปแล้วไม่จำเป็นต้องใช้คุกกี้สำหรับ AJAX สนับสนุน XmlHttpRequest (หรือแม้กระทั่ง iframe remoting บนเบราว์เซอร์รุ่นเก่า) เป็นสิ่งที่จำเป็นในทางเทคนิค

อย่างไรก็ตามหากคุณต้องการความปลอดภัยสำหรับฟังก์ชั่นที่เปิดใช้งาน AJAX กฎเดียวกันจะมีผลบังคับใช้กับไซต์ทั่วไป คุณต้องใช้วิธีการบางอย่างในการระบุผู้ใช้ที่อยู่เบื้องหลังคำขอแต่ละครั้งและคุกกี้มักจะหมายถึงจุดสิ้นสุดนั้นเสมอ

ในตัวอย่างของคุณฉันไม่สามารถเขียนไปที่ document.cookie ของคุณ แต่ฉันยังสามารถขโมยคุกกี้ของคุณและโพสต์ไปยังโดเมนของฉันโดยใช้วัตถุ XMLHttpRequest

XmlHttpRequest จะไม่ขอข้ามโดเมน (ด้วยเหตุผลหลายประการที่คุณสัมผัส)

โดยปกติคุณสามารถฉีดสคริปต์เพื่อส่งคุกกี้ไปยังโดเมนของคุณโดยใช้ iframe remoting หรือ JSONP แต่จากนั้น HTTP-Only จะป้องกันคุกกี้อีกครั้งเนื่องจากไม่สามารถเข้าถึงได้

StackOverflow.com ทางฝั่งเซิร์ฟเวอร์คุณจะไม่สามารถขโมยคุกกี้ของฉันได้

แก้ไข 2: คำถามที่ 2 หากจุดประสงค์ของ Http-Only คือเพื่อป้องกันไม่ให้ JavaScript เข้าถึงคุกกี้และคุณยังสามารถเรียกดูคุกกี้ผ่าน JavaScript ผ่าน XmlHttpRequest Object ได้จุดของ Http-Only คืออะไร

พิจารณาสถานการณ์นี้:

  • ฉันพบถนนเพื่อฉีดโค้ด JavaScript ลงในหน้า
  • Jeff โหลดหน้าเว็บและ JavaScript ที่เป็นอันตรายของฉันจะแก้ไขคุกกี้ของเขาเพื่อให้ตรงกับของฉัน
  • Jeff ส่งคำตอบที่เป็นตัวเอกสำหรับคำถามของคุณ
  • เนื่องจากเขาส่งข้อมูลคุกกี้ของฉันแทนเขาคำตอบจะกลายเป็นของฉัน
  • คุณโหวตคำตอบที่เป็นตัวเอก "ของฉัน"
  • บัญชีจริงของฉันได้รับคะแนน

ด้วยคุกกี้ HTTP เท่านั้นขั้นตอนที่สองจะเป็นไปไม่ได้ดังนั้นการเอาชนะความพยายาม XSS ของฉัน

แก้ไข 4: ขออภัยฉันหมายความว่าคุณสามารถส่ง XMLHttpRequest ไปยังโดเมน StackOverflow และจากนั้นบันทึกผลลัพธ์ของ getAllResponseHeaders () ไปยังสตริงลงทะเบียนคุกกี้แล้วโพสต์นั้นไปยังโดเมนภายนอก ดูเหมือนว่า Wikipedia และ ha.ckers เห็นด้วยกับฉันในเรื่องนี้ แต่ฉันจะรักการศึกษา ...

ถูกต้อง. คุณยังคงสามารถเซสชั่นจี้ได้ มันทำให้ฝูงคนที่ประสบความสำเร็จสามารถดำเนินการได้แม้ว่า XSS จะทำการแฮ็คกับคุณ

อย่างไรก็ตามถ้าคุณกลับไปที่สถานการณ์ตัวอย่างของฉันคุณสามารถดูได้ว่า HTTP-Only ทำที่ใดประสบความสำเร็จในการตัดการโจมตี XSS ซึ่งพึ่งพาการปรับเปลี่ยนคุกกี้ของลูกค้า (ไม่ใช่เรื่องแปลก)

มันทำให้ความจริงที่ว่า a) ไม่มีการปรับปรุงเพียงอย่างเดียวที่จะแก้ไขช่องโหว่ทั้งหมดและ b) ไม่มีระบบใดที่ปลอดภัยอย่างสมบูรณ์ HTTP เท่านั้นคือเครื่องมือที่มีประโยชน์ในการแบ่งส่วนกับ XSS

ในทำนองเดียวกันแม้ว่าข้อ จำกัด ข้ามโดเมนใน XmlHttpRequest นั้นไม่ประสบความสำเร็จ 100% ในการป้องกันการโกง XSS ทั้งหมด แต่คุณก็ยังไม่เคยฝันที่จะลบข้อ จำกัด


กรอบหลายคนใส่เครื่องหมายในคุกกี้csrf ฉันคิดว่าการโทร AJAX ที่ต้องการการcsrfตรวจสอบจะไม่ทำงานจนกว่าคุณจะใส่โทเค็น csrf ในองค์ประกอบ HTML ที่ซ่อนอยู่สำหรับ JS เพื่อเรียกคืน
ผู้ใช้

4

ไม่จำเป็นขึ้นอยู่กับว่าคุณต้องการทำอะไร คุณอธิบายรายละเอียดเล็กน้อยได้ไหม? AJAX ไม่จำเป็นต้องเข้าถึงคุกกี้เพื่อทำงานมันสามารถทำการร้องขอด้วยตัวเองเพื่อดึงข้อมูลหน้าร้องขอที่การเรียก AJAX สามารถเข้าถึงข้อมูลคุกกี้ & ส่งผ่านกลับไปที่สคริปต์การโทรโดยที่ Javascript ไม่จำเป็นต้องเข้าถึงโดยตรง คุ้กกี้


4

ใช่พวกเขาเป็นตัวเลือกที่ทำงานได้สำหรับไซต์ที่ใช้ Ajax คุกกี้การตรวจสอบความถูกต้องไม่ได้มีไว้สำหรับการจัดการโดยสคริปต์ แต่จะรวมอยู่ในเบราว์เซอร์บนคำขอ HTTP ทั้งหมดที่ส่งไปยังเซิร์ฟเวอร์

สคริปต์ไม่จำเป็นต้องกังวลเกี่ยวกับสิ่งที่คุกกี้เซสชันพูดถึง - ตราบใดที่คุณได้รับการรับรองความถูกต้องจากนั้นคำขอใด ๆ ไปยังเซิร์ฟเวอร์ที่ริเริ่มโดยผู้ใช้หรือสคริปต์จะมีคุกกี้ที่เหมาะสม ความจริงที่ว่าสคริปต์ไม่สามารถรู้เนื้อหาของคุกกี้ได้

สำหรับคุกกี้ใด ๆ ที่ใช้เพื่อวัตถุประสงค์อื่นนอกเหนือจากการตรวจสอบความถูกต้องสามารถตั้งค่าได้โดยไม่ต้องตั้งค่าสถานะ HTTP เท่านั้นหากคุณต้องการให้สคริปต์สามารถแก้ไขหรืออ่านได้ คุณสามารถเลือกและเลือกคุกกี้ที่ควรเป็น HTTP เท่านั้นดังนั้นตัวอย่างเช่นสิ่งที่ไม่ไวต่อการกำหนดค่า UI (ลำดับการเรียงการยุบบานหน้าต่างด้านซ้ายมือหรือไม่) สามารถแชร์ในคุกกี้ด้วยสคริปต์

ฉันชอบคุกกี้ HTTP เท่านั้นจริงๆ - เป็นหนึ่งในส่วนขยายเบราว์เซอร์ที่เป็นกรรมสิทธิ์ซึ่งเป็นแนวคิดที่ยอดเยี่ยมจริงๆ


3

มันมีอะไรมากกว่านี้

Ajax ไม่ต้องการคุกกี้อย่างเข้มงวด แต่สามารถมีประโยชน์ได้เช่นเดียวกับผู้โพสต์อื่น ๆ การทำเครื่องหมายคุกกี้ HTTPOnly เพื่อซ่อนจากสคริปต์ใช้งานได้เพียงบางส่วนเท่านั้นเนื่องจากเบราว์เซอร์บางตัวไม่สนับสนุน แต่รวมถึงเนื่องจากมีวิธีแก้ไขปัญหาทั่วไป

เป็นเรื่องแปลกที่ส่วนหัวของ XMLHTTPresponse ให้คุกกี้โดยทางเทคนิคแล้วเซิร์ฟเวอร์ไม่จำเป็นต้องส่งคืนคุกกี้ด้วยการตอบกลับ เมื่อตั้งค่าบนไคลเอนต์มันจะยังคงตั้งค่าจนกว่าจะหมดอายุ แม้ว่าจะมีรูปแบบที่คุกกี้เปลี่ยนไปด้วยทุกคำขอเพื่อป้องกันการใช้ซ้ำ ดังนั้นคุณอาจหลีกเลี่ยงปัญหาดังกล่าวได้โดยเปลี่ยนเซิร์ฟเวอร์เพื่อไม่ให้คุกกี้ในการตอบสนอง XMLHTTP

โดยทั่วไปแล้วฉันคิดว่า HTTPOnly ควรใช้ด้วยความระมัดระวัง มีการโจมตีสคริปต์ข้ามไซต์โดยที่ผู้โจมตีจัดให้ผู้ใช้ส่งคำร้องขอ ajax ที่มาจากไซต์อื่นโดยใช้แบบฟอร์มการโพสต์อย่างง่ายโดยไม่ต้องใช้ XMLHTTP และคุกกี้ที่ยังทำงานอยู่ของเบราว์เซอร์จะตรวจสอบความถูกต้องของคำขอ

หากคุณต้องการให้แน่ใจว่าคำขอ AJAX ได้รับการรับรองความถูกต้องคำขอของตัวเองและส่วนหัว HTTP จะต้องมีคุกกี้ เช่นผ่านการใช้สคริปต์หรืออินพุตที่ไม่ซ้ำกัน HTTPOnly จะขัดขวางสิ่งนั้น

โดยทั่วไปแล้วเหตุผลที่น่าสนใจที่จะต้องการ HTTPOnly คือการป้องกันไม่ให้เนื้อหาของบุคคลที่สามที่รวมอยู่ในหน้าเว็บของคุณขโมยคุกกี้ แต่มีเหตุผลที่น่าสนใจมากมายที่ต้องระมัดระวังอย่างมากเกี่ยวกับการรวมเนื้อหาของบุคคลที่สามและกรองอย่างจริงจัง


1

เบราว์เซอร์จะจัดการคุกกี้โดยอัตโนมัติเมื่อคุณทำการโทร AJAX ดังนั้นจึงไม่จำเป็นที่ Javascript ของคุณจะยุ่งกับคุกกี้


1

ดังนั้นฉันสมมติว่า JavaScript ต้องเข้าถึงคุกกี้ของคุณ

คำขอ HTTP ทั้งหมดจากเบราว์เซอร์ของคุณส่งข้อมูลคุกกี้ของคุณสำหรับไซต์ที่เป็นปัญหา JavaScript สามารถตั้งค่าและอ่านคุกกี้ได้ คุกกี้ไม่ได้เป็นข้อกำหนดตามที่กำหนดสำหรับแอปพลิเคชัน Ajax แต่เป็นสิ่งจำเป็นสำหรับเว็บแอปพลิเคชันส่วนใหญ่เพื่อรักษาสถานะผู้ใช้

คำตอบที่เป็นทางการสำหรับคำถามของคุณเป็นวลี - "JavaScript จำเป็นต้องเข้าถึงคุกกี้หรือไม่หากใช้ AJAX?" - จึงเป็น "ไม่" นึกถึงช่องค้นหาที่ได้รับการปรับปรุงซึ่งใช้คำขอ Ajax เพื่อให้ตัวเลือกแนะนำอัตโนมัติเช่น ไม่จำเป็นต้องมีข้อมูลคุกกี้ในกรณีนี้


XmlHttpRequest ต้องการคุกกี้ การค้นหาขั้นสูงที่คุณพูดถึงอาจอยู่ด้านหลังหน้าเข้าสู่ระบบ แต่จาวาสคริปต์นั้นจำเป็นต้องเปิดเผยค่าคุกกี้ให้กับ VM หรือไม่นั้นเป็นคำถามที่แตกต่างออกไป
นายเงางามและใหม่安宇

1

ในฐานะที่เป็นคำชี้แจง - จากมุมมองของเซิร์ฟเวอร์หน้าเว็บที่ร้องขอโดยคำขอ AJAX นั้นไม่แตกต่างจากคำขอมาตรฐานที่ HTTP ทำโดยผู้ใช้คลิกที่ลิงค์ คุณสมบัติการร้องขอปกติทั้งหมด: user-agent, ip, session, cookies, ฯลฯ จะถูกส่งไปยังเซิร์ฟเวอร์


"เซสชัน" ไม่ใช่แนวคิด HTTP มันเป็นแนวคิดระดับสูงที่สร้างขึ้นจากแนวคิด HTTP โดยกรอบงาน
curiousguy

0

ไม่หน้าเว็บที่ร้องขอการโทร AJAX สามารถเข้าถึงคุกกี้ได้ด้วย & นั่นคือสิ่งที่ตรวจสอบว่าคุณลงชื่อเข้าใช้หรือไม่

คุณสามารถทำการรับรองความถูกต้องอื่น ๆ ด้วย Javascript ได้ แต่ฉันไม่ไว้ใจมันฉันมักจะชอบที่จะทำการตรวจสอบความถูกต้องในแบ็คเอนด์


0

ใช่คุกกี้มีประโยชน์มากสำหรับ Ajax

การวางการรับรองความถูกต้องใน URL ที่ขอเป็นสิ่งที่ไม่ดี มีรายการข่าวเมื่อสัปดาห์ที่แล้วเกี่ยวกับการรับโทเค็นการรับรองความถูกต้องใน URL จากแคชของ Google

ไม่ไม่มีวิธีในการป้องกันการโจมตี เบราว์เซอร์รุ่นเก่ายังคงอนุญาตให้เข้าถึงคุกกี้ผ่าน javascript ได้เล็กน้อย คุณสามารถเลี่ยง http เท่านั้นเป็นต้นไม่ว่าคุณจะทำอะไรก็ตามจะได้รับความพยายามเพียงพอ เคล็ดลับคือการใช้ความพยายามมากเกินไปที่จะคุ้มค่า

หากคุณต้องการทำให้เว็บไซต์ของคุณปลอดภัยมากขึ้น (ไม่มีความปลอดภัยที่สมบูรณ์แบบ) คุณสามารถใช้คุกกี้รับรองความถูกต้องที่หมดอายุ จากนั้นหากคุกกี้ถูกขโมยผู้โจมตีจะต้องใช้มันก่อนที่มันจะหมดอายุ หากพวกเขาไม่มีคุณมีข้อบ่งชี้ที่ดีว่ามีกิจกรรมที่น่าสงสัยในบัญชีนั้น หน้าต่างเวลาที่สั้นกว่าจะดีกว่าสำหรับการรักษาความปลอดภัย แต่ยิ่งโหลดมากเท่าไหร่ก็ยิ่งทำให้เซิร์ฟเวอร์ของคุณสร้างและบำรุงรักษาคีย์ได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.