'ข้อมูลที่ละเอียดอ่อน' สามารถเปิดเผยอะไรได้บ้างเมื่อตั้งค่า JsonRequestBehavior เป็น AllowGet


112

ฉันได้รับข้อผิดพลาดเดิมทุกครั้งที่ฉันทดสอบใหม่URLจากแถบที่อยู่ของเบราว์เซอร์เมื่อฉันreturning Json(ใช้งานในตัวMVC JsonResult helper):

คำขอนี้ถูกบล็อกเนื่องจากอาจมีการเปิดเผยข้อมูลที่ละเอียดอ่อนไปยังเว็บไซต์ของบุคคลที่สามเมื่อใช้สิ่งนี้ในไฟล์GET request. ในการอนุญาตให้GET requestsชุดที่จะJsonRequestBehaviorAllowGet

แทนที่จะฮึดฮัดในการรับทราบและกระตุ้นให้ Fiddler ทำคำขอโพสต์คราวนี้ฉันสงสัยว่าGETคำขอนั้นคืออะไรที่เปิดเผยว่าPOSTคำขอนั้นไม่?

คำตอบ:


82

สมมติว่าเว็บไซต์ของคุณมีGetUserวิธีการใช้เว็บ:

http://www.example.com/User/GetUser/32

ซึ่งส่งคืนการตอบสนอง JSON:

{ "Name": "John Doe" }

หากวิธีนี้ยอมรับเฉพาะคำขอ POST เนื้อหาจะถูกส่งกลับไปยังเบราว์เซอร์ก็ต่อเมื่อมีการร้องขอ AJAX http://www.example.com/User/GetUser/32โดยใช้วิธีการ POST โปรดทราบว่าหากคุณไม่ได้ติดตั้งCORSเบราว์เซอร์จะปกป้องข้อมูลจากโดเมนอื่นที่ส่งคำขอนี้ถึงคุณ

อย่างไรก็ตามหากคุณอนุญาตคำขอ GET และสร้างคำขอ AJAX ที่คล้ายกับข้างต้นด้วย GET แทนที่จะเป็น POST ผู้ใช้ที่เป็นอันตรายอาจรวม JSON ของคุณไว้ในบริบทของไซต์ของตนโดยใช้scriptแท็กใน HTML เช่นเมื่อwww.evil.com:

<script src="http://www.example.com/User/GetUser/32"></script>

JavaScript นี้ไม่ควรใช้www.evil.comเพราะไม่มีวิธีอ่านวัตถุที่ส่งคืนโดยวิธีการเว็บของคุณ อย่างไรก็ตามเนื่องจากข้อบกพร่องในเบราว์เซอร์เวอร์ชันเก่า (เช่น Firefox 3) จึงเป็นไปได้ที่วัตถุต้นแบบ JavaScript จะถูกกำหนดใหม่และทำให้สามารถwww.evil.comอ่านข้อมูลของคุณที่ส่งคืนโดยวิธีการของคุณได้ สิ่งนี้เรียกว่า JSON Hijacking

ดูโพสต์นี้สำหรับวิธีการบางอย่างในการป้องกันปัญหานี้ อย่างไรก็ตามไม่ใช่ปัญหาที่ทราบกันดีกับเบราว์เซอร์สมัยใหม่รุ่นใหม่ ๆ (Firefox, Chrome, IE)


25
โพสต์ได้ดี แต่ถ้าคุณใส่แท็ก [Authorize] ลงในคอนโทรลเลอร์คุณก็ไม่ต้องกังวลเรื่องความปลอดภัย หวังว่ารหัสนี้จะช่วยใครสักคน Json (returnMsg, JsonRequestBehavior.A allowGet)
Dhanuka777

17
@ Dhanuka777: ไม่จริงน่าเสียดาย การโจมตีCSRFอาจเกิดขึ้นได้หากวิธีการดังกล่าวมีผลข้างเคียง (เช่นwww.example.com/User/DeleteUser/32) เนื่องจากการร้องขอจะรวมคุกกี้ที่จำเป็นสำหรับการตรวจสอบสิทธิ์เนื่องจากมาจากเครื่องของเหยื่อ [Authorize]จะไม่ช่วยคุณจากการโจมตีรายละเอียดที่นี่ในกรณีของเบราว์เซอร์ที่เก่าแก่มากอย่างใดอย่างหนึ่ง - มันเป็นผู้ที่เข้ามาเยี่ยมชมตัวเองwww.evil.comเพื่อร้องขอwww.evil.comทำให้www.example.comจะมีคุกกี้อนุมัติ
SilverlightFox

1
และหากการกระทำมีผลข้างเคียงใด ๆ ก็ไม่ควรเรียกใช้โดยใช้เมธอด GET - หลักการคือการใช้ GET เพียงเพื่ออ่านข้อมูลและการดำเนินการที่มีผลข้างเคียงทั้งหมดควรใช้ POST, PUT, DELETE เป็นต้นกล่าวอีกนัยหนึ่งคือ I เพียงแค่คิดว่าข้อความแสดงข้อผิดพลาด "ข้อมูลที่ละเอียดอ่อน" นี้ทำให้เข้าใจผิด หากนักพัฒนาใช้เมธอด GET ตามที่ควรใช้ทุกอย่างก็เรียบร้อย! :)
ps_ttf

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

1
@ คาสโตรเฮนจ์: ไม่เพราะต้องตั้งค่าส่วนหัวซึ่งจะไม่ถูกส่งไปพร้อมกับคำขอ GET สำหรับสคริปต์ src
SilverlightFox

111

ในการส่งคืนของคุณให้ใช้สิ่งต่อไปนี้:

return this.Json("you result", JsonRequestBehavior.AllowGet);

7
สิ่งนี้ตอบคำถามของ OP ได้อย่างไร? คำตอบทั้งหมดนี้บอกทุกคนว่าจะหลีกเลี่ยงข้อยกเว้นได้อย่างไร ..
eaglei22

2
ใช่ใช้มัน .. เหมือนลองจับด้วยเปล่า อย่าใช้พวกนี้ (ก่อนที่คุณจะเข้าใจความเสี่ยง) -1'd
sotn

6
ไม่มีความรับผิดชอบที่จะบอกให้ผู้คนเพิกเฉยต่อคำเตือนด้านความปลอดภัยโดยไม่ต้องอธิบายผลที่ตามมา -1
Eduardo Wada

58

โดยค่าเริ่มต้นเฟรมเวิร์ก ASP.NET MVC ไม่อนุญาตให้คุณตอบสนองต่อคำขอ GET ด้วยเพย์โหลด JSON เนื่องจากมีโอกาสที่ผู้ใช้ที่ประสงค์ร้ายสามารถเข้าถึงเพย์โหลดผ่านกระบวนการที่เรียกว่า JSON Hijacking คุณไม่ต้องการส่งคืนข้อมูลที่ละเอียดอ่อนโดยใช้ JSON ในคำขอ GET

หากคุณต้องการส่ง JSON เพื่อตอบสนองต่อ GET และไม่เปิดเผยข้อมูลที่ละเอียดอ่อนคุณสามารถอนุญาตให้เกิดพฤติกรรมได้อย่างชัดเจนโดยส่งJsonRequestBehavior.AllowGetพารามิเตอร์ที่สองไปยังJson เมธอด

เช่น

  [HttpGet] //No need to decorate, as by default it will be GET
  public JsonResult GetMyData(){  
    var myResultDataObject = buildMyData(); // build, but keep controller thin
    // delegating buildMyData to builder/Query Builder using CQRS makes easy :)
    return Json(myResultDataObject, JsonRequestBehavior.AllowGet);
  }

นี่คือบทความที่น่าสนใจจาก Phil Haack JSON Hijackingเกี่ยวกับสาเหตุที่ไม่ใช้ Json ด้วยวิธี GET


2
โพสต์ที่ดี เหตุผลที่ดีที่คุณควรใช้ HTTPS
pqsk

6
ฉันไม่คิดว่า HTTPS ช่วยตรงนี้
Sean McMillan

10

เมื่อเราต้องการส่งคืนวัตถุ json ไปยังไคลเอนต์จากแอปพลิเคชัน MVC เราควรระบุ JsonRequestBehavior.A allowGet อย่างชัดเจนเมื่อส่งคืนวัตถุ เป็นผลให้ฉันส่งคืนข้อมูล json ด้านล่างเพื่อแก้ไขปัญหา:

    return Json(yourObjectData, JsonRequestBehavior.AllowGet);

7

คุณต้องใช้ JsonRequestBehavior.A allowGet สำหรับการตอบสนอง Json ดังนี้:

return Json(YourObject, JsonRequestBehavior.AllowGet);

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