900 เว็บไซต์, 125 ล้านบัญชี, 1 ช่องโหว่
(env.fail)- การตั้งค่า กฎความปลอดภัยของ Firebase ผิดพลาดเพียงจุดเดียว นำไปสู่การเปิดเผยข้อมูลผู้ใช้ของเว็บไซต์หลายร้อยแห่ง โดยขนาดที่ยืนยันแล้วมีอย่างน้อยประมาณ 124.6 ล้านเรคอร์ด
- การสืบสวนเริ่มต้นด้วยการค้นหา ตัวแปรการตั้งค่า Firebase ในเว็บไซต์และ JavaScript bundle ที่ถูกโหลด และถูกเขียนใหม่จาก Python เป็น Go เพราะปัญหาหน่วยความจำของสแกนเนอร์ Python
- สแกนเนอร์เสริม Catalyst จะตรวจสอบโดยอัตโนมัติว่า Firebase collection อ่านได้หรือไม่ และประเมินประเภทและขนาดของข้อมูลที่ถูกเปิดเผยจากข้อมูลตัวอย่าง
- รายการข้อมูลที่ถูกเปิดเผยซึ่งถูกรวบรวมได้มี ชื่อ 84,221,169 รายการ, อีเมล 106,266,766 รายการ, หมายเลขโทรศัพท์ 33,559,863 รายการ, รหัสผ่านแบบ plaintext 20,185,831 รายการ, และข้อมูลการชำระเงิน 27,487,924 รายการ
- ทีมนักวิจัยส่งอีเมลแจ้งเตือน 842 ฉบับภายใน 13 วัน แต่มีเจ้าของเว็บไซต์เพียง 24% ที่แก้ไขการตั้งค่า, 1% ที่ตอบกลับ และมีเพียง 2 เว็บไซต์ที่เสนอ bug bounty
การสแกนการเปิดเผย Firebase ในระดับอินเทอร์เน็ต
- หลังกรณีการละเมิดของ Chattr.ai ก็เริ่มมีการ สแกนทั้งอินเทอร์เน็ต เพื่อค้นหา PII ที่ถูกเปิดเผยผ่าน Firebase instance ที่ตั้งค่าผิด
- สแกนเนอร์ Python ตัวแรกตรวจสอบตัวแปรการตั้งค่า Firebase จากเว็บไซต์หรือ
.jsbundle ที่ถูกโหลด แต่เมื่อทำงานที่ประมาณ 500 เธรด การใช้หน่วยความจำก็เพิ่มขึ้นและเกิด OOM ภายใน 1 ชั่วโมง - หลังจากนั้นสแกนเนอร์ที่เขียนใหม่ด้วย Go ถูกนำไปรันกับ 5.5 ล้านโดเมน และใช้เวลานาน 2–3 สัปดาห์ ซึ่งนานกว่าที่คาดไว้ตอนแรกประมาณ 11 วัน
- เพียงการตรวจสอบด้วยมือในช่วงแรกก็พบแล้ว 136 เว็บไซต์และ 6.2 ล้านเรคอร์ด แต่เมื่อรายการตัวเลือกมีขนาดใหญ่มากขึ้น จึงจำเป็นต้องทำให้เป็นอัตโนมัติทั้งหมด
Catalyst และการประเมินขนาดการเปิดเผยข้อมูล
- Catalyst รับเว็บไซต์หรือ JavaScript bundle ที่เป็นตัวเลือกเป็นอินพุต แล้วตรวจสอบโดยอัตโนมัติว่าสามารถอ่าน Firebase collection ทั่วไปและ collection ที่ถูกอ้างถึงตรง ๆ ใน JavaScript ได้หรือไม่
- เมื่อพบ collection ที่อ่านได้ ระบบจะเก็บตัวอย่าง 100 เรคอร์ดเพื่อตรวจสอบประเภทข้อมูลที่มีอยู่ แล้วคูณกับขนาดทั้งหมดของ collection เพื่อประเมินผลกระทบ
- สำหรับคลังเก็บผลลัพธ์ ได้เลือกใช้ Supabase ซึ่งเป็นคู่แข่งโอเพนซอร์สของ Firebase ที่ใช้ PostgreSQL และข้อมูลที่จัดระเบียบแล้วถูกอัปโหลดไปยังตารางฐานข้อมูลแบบไม่เปิดเผยต่อสาธารณะ
- ตัวเลขสรุปมีดังนี้ และขนาดการเปิดเผยจริงอาจมากกว่าตัวเลขที่แสดง
- เรคอร์ดทั้งหมด: 124,605,664 รายการ
- ชื่อ: 84,221,169 รายการ
- อีเมล: 106,266,766 รายการ
- หมายเลขโทรศัพท์: 33,559,863 รายการ
- รหัสผ่าน: 20,185,831 รายการ
- ข้อมูลการชำระเงิน: ข้อมูลธนาคาร, ใบแจ้งหนี้ ฯลฯ 27,487,924 รายการ
เว็บไซต์ที่ได้รับผลกระทบหนัก
-
Silid LMS
- ระบบจัดการการเรียนรู้สำหรับนักเรียนและครู
- มีการเปิดเผยเรคอร์ดผู้ใช้ 27 ล้านคน รวมถึงชื่อ อีเมล และหมายเลขโทรศัพท์ มากที่สุดในบรรดาทั้งหมด
-
เครือข่ายพนันออนไลน์
- ประกอบด้วย 9 เว็บไซต์ที่รีสกินจากกันและกัน
- การหมุนบางแบบถูกปรับแต่งให้มีโอกาสชนะ 0%
- ข้อมูลล็อกอินรายละเอียดบัญชีธนาคารถูกเปิดเผยมากที่สุดที่ 8 ล้านรายการ
- รหัสผ่านแบบ plaintext ก็ได้รับผลกระทบมากที่สุดเช่นกันที่ 10 ล้านรายการ
- ระหว่างกระบวนการพยายามแจ้งปัญหา ฝ่ายสนับสนุนลูกค้ากลับโปรยเสน่ห์ใส่ระหว่างสนทนา
-
Lead Carrot
- บริการสร้างลีดออนไลน์สำหรับการโทรหาลูกค้าแบบ cold call
- ปริมาณข้อมูลผู้ใช้ที่ถูกเปิดเผยอยู่ในอันดับ 3 และส่งผลกระทบต่อ 22 ล้านคน
-
MyChefTool
- แอปบริหารธุรกิจและแอปพลิเคชัน POS สำหรับร้านอาหาร
- มีจำนวนชื่อที่ถูกเปิดเผยมากที่สุด และจำนวนอีเมลที่ถูกเปิดเผยมากเป็นอันดับ 2 โดยถูกเปิดเผยอย่างละ 14 ล้านรายการ และ 13 ล้านรายการ ตามลำดับ
ปฏิกิริยาหลังการแจ้งเตือน
- ทีมนักวิจัยส่ง อีเมล 842 ฉบับ ภายใน 13 วัน
- 85% ถูกส่งถึง และ 9% ตีกลับ
- เจ้าของเว็บไซต์ 24% แก้ไขการตั้งค่าที่ผิดพลาด
- เจ้าของเว็บไซต์ที่ตอบกลับมีเพียง 1%
- เจ้าของเว็บไซต์ 2 ราย หรือ 0.2% เสนอ bug bounty
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ผมทำงานที่ Firebase มานาน และปัญหาเรื่อง กฎความปลอดภัย ก็รบกวนผลิตภัณฑ์นี้มาตลอด
เคยลองหลายแนวทาง เช่น กฎเริ่มต้นที่หมดอายุอัตโนมัติ การเพิ่มการให้ความรู้ แต่สุดท้ายก็ยังเห็นฐานข้อมูลจำนวนมากที่ไม่ปลอดภัยอยู่ดี
เหตุผลค่อนข้างซับซ้อน แต่กฎความปลอดภัยแบบ Firebase ยังเป็นแนวคิดที่ไม่คุ้นเคย และนักพัฒนาใหม่ที่เพิ่มข้อมูลเข้าไปในตำแหน่งเดิมก็มักไม่แก้กฎให้สอดคล้องกับข้อกำหนดด้านความเป็นส่วนตัวของข้อมูลที่เปลี่ยนไป
อีกอย่างคือ “ความปลอดภัยจากความคลุมเครือ” ที่แบ็กเอนด์ที่แต่ละคนทำเองเคยมีนั้นหายไป ทำให้การสแกนในวงกว้างทำได้ง่ายขึ้น
โดยเฉพาะกฎของ Realtime Database นั้นเขียนยากและขยายต่อได้ไม่ดี แต่การสแกนอัตโนมัติมักมองหาแค่ข้อมูลที่เปิดอยู่ ดังนั้นถ้าดีกว่า
read write trueเพียงเล็กน้อยก็พอจะกันได้ในทางเทคนิค แนวทางของ Firebase เองไม่ได้ผิด แต่เพราะแทบจะเป็นแบ็กเอนด์รายเดียวที่ใช้โมเดลที่เน้นข้อมูลที่จัดเก็บกับกฎความปลอดภัย จึงเสี่ยงต่อความเข้าใจผิด การใช้งานผิด และเหตุการณ์แบบนี้ได้ง่าย
ในแบ็กเอนด์ การตรวจสอบความถูกต้องและกฎความปลอดภัยดูเหมือนเป็นส่วนหนึ่งของสเปก แต่กฎความปลอดภัยของ Firebase เป็นกระบวนการแยกต่างหาก จึงลืมได้ง่าย และต้องประเมินใหม่ทุกครั้งที่สร้างฟีเจอร์ใหม่
ถ้าจะดึงความสนใจจากคนที่แจ้งเจ้าของโปรเจกต์ได้ คงต้อง escalate ภายใน Firebase ไปค่อนข้างสูง
เช่น เทมเพลตในบทความอย่าง “เฉพาะเจ้าของคอนเทนต์เข้าถึงได้” หรือ “การเข้าถึงตามคุณสมบัติและตามบทบาท” จะครอบคลุมแพตเทิร์นของแอปส่วนใหญ่ได้หรือไม่ หรือจริง ๆ แล้วยังต้องใช้กฎแบบปรับแต่งเองจำนวนมาก
ปัญหาใหญ่ของการเขียนกฎความปลอดภัยคือความผิดพลาดแทบทุกอย่างกลายเป็นปัญหาความปลอดภัย จึงไม่อยากไปแตะถ้าไม่จำเป็น
ถ้ากฎล็อกแน่นเกินไป แอปจะไม่ทำงานและเห็นได้ทันที แต่ถ้าเปิดกว้างเกินไป มักไม่เห็นชัดจนกว่าจะลองเจาะการเข้าถึงที่เกินสิทธิ์เอง
ในเรื่องนี้ ก็น่าคิดถึงวิธีบังคับให้นักพัฒนาเขียนเคสทดสอบตัวอย่างการปฏิเสธการเข้าถึงสำหรับกฎความปลอดภัยแต่ละข้อด้วย
fireplanจะเพิ่มกฎเริ่มต้น"$other": {".read": false, ".write": false}ให้กับทุก propertyด้วยเหตุนี้ ฟิลด์ใหม่ต้องถูกเพิ่มอย่างชัดเจน ทำให้แทบเป็นไปไม่ได้ที่ค่าใหม่จะ “สืบทอด” กฎเดิมโดยไม่รู้ตัว
เราใช้ Firebase มานานกว่า 10 ปีแล้ว จึงไม่รู้ว่าเครื่องมือกฎรุ่นใหม่ทำแบบนี้ด้วยหรือไม่
สิ่งที่จะช่วยได้จริง ๆ คือการรองรับพื้นฐานสำหรับการเปลี่ยนชื่อฟิลด์หรือเปลี่ยนโครงสร้างข้อมูลในสถานการณ์ที่มีไคลเอนต์หลายเวอร์ชันที่ควบคุมได้ยาก วิธีทดสอบกฎแบบเบา ๆ โดยไม่ต้องเปิดฐานข้อมูล และข้อมูลดีบักที่ดีกว่าเมื่อกฎล้มเหลวในสภาพแวดล้อม production
ทุกครั้งที่ล้มเหลว ควรบันทึกค่าทั้งหมดที่กฎเข้าถึงไว้ด้วย จึงจะดีบักความล้มเหลวชั่วคราวที่เกิดจากข้อมูลที่เปลี่ยนแปลงได้
นี่คือ โมเดลเชิงแนวคิด ที่ยังอธิบายไม่เพียงพอ
ในโปรเจกต์ เราจะบอกว่าแต่ละ collection ควรมีโปรไฟล์ความปลอดภัย เช่น สาธารณะ ข้อมูลผู้ใช้ เปิดให้เฉพาะผู้ใช้ที่ยืนยันตัวตนแล้ว หรือเฉพาะแอดมิน และใช้แนวทางบังคับหมวดหมู่เหล่านี้ด้วยฟังก์ชันกฎความปลอดภัย แทนที่จะเขียนเงื่อนไขเฉพาะสำหรับแต่ละ collection
ถ้าคิดเรื่องความปลอดภัยในระดับ collection แทนระดับฟิลด์ ก็จะลดการปะปนของเจตนาด้านความปลอดภัยที่ต่างกันภายในเอกสารเดียวกันได้
ถ้า collection เป็นสาธารณะ ก็ไม่ควรมีฟิลด์ที่ไม่ใช่สาธารณะอยู่ในนั้น และหากจำเป็น สามารถใช้ Firestore trigger เพื่อคัดลอกข้อมูลจาก context ที่อ่อนไหวไปยัง context สาธารณะได้ แต่ไม่ควรทำในทิศทางกลับกัน
ปัญหาคือต้องทำเอกสารอธิบายเจตนาของกฎไว้นอกตัวกฎเอง จึงนำไปใช้ผิดได้ง่าย และเมื่อก่อนการเขียนเทสต์ก็ทรมานมาก แต่ตอนนี้ดีขึ้นมากแล้ว
นึกถึง “How I pwned half of America’s fast food chains, simultaneously.”: https://mrbruh.com/chattr/
HN: https://news.ycombinator.com/item?id=38933999
After the initial buzz of [pwning Chattr.ai] had settled down, […]ถ้าผมไม่ได้ดูผิด หมายความว่า ณ ตอนท้ายของบทความ 75% ของเว็บไซต์ที่มีช่องโหว่แบบนี้ยังคงเปิดอยู่และ dump ได้เหมือนเดิมไม่ใช่หรือ?
บ้ามาก
บางวันก็อดคิดไม่ได้ว่าควรต้องมีใบอนุญาตก่อนถึงจะจับคอมพิวเตอร์ได้
พวกเขาจ้างเอเจนซีทำเว็บไซต์แบบ outsource และเอเจนซีก็เปลี่ยนนักพัฒนาไปเรื่อย ๆ ตอนแรกอาจจัดนักพัฒนาที่ดีให้ แต่หลังจากนั้นถ้าบริษัทไม่บ่น ก็ส่งสัญญาไปให้นักพัฒนาที่ทักษะน้อยกว่า
อีเมลแจ้งช่องโหว่อาจถูกมองเป็นสแปมแล้วเพิกเฉย หรือถูกส่งต่อแล้วปล่อยทิ้งไว้ หรือไปอยู่ในคิวตารางประชุมของ PM กลายเป็นรายการที่รอแก้โดยพยายามคิดเงินลูกค้าให้ได้มากที่สุด
แม้ในสาขาที่บังคับให้มีใบอนุญาตวิชาชีพ ก็ยังมีผู้ถือใบอนุญาตที่ไร้ความสามารถจำนวนมาก
แพทย์เองก็มีข้อกำหนดด้านการศึกษาและใบอนุญาตสูงมาก แต่ก็ไม่ได้ขาดแคลนหมอเถื่อนกับผู้ประกอบวิชาชีพแพทย์ทางเลือกที่มีใบอนุญาต
ผมพยายามเต็มที่แล้วโดยส่ง อีเมลเฉพาะราย ไปยังแต่ละไซต์ ระบุว่าได้รับผลกระทบอะไร วิธีแก้ไข และวิธีติดต่อ
นี่เป็นผลลัพธ์ที่เลี่ยงไม่ได้จากการที่ PM เลือกทาง ถูกและเร็ว ในสามเหลี่ยม cheap-fast-good
น่าเสียดายที่ความกังวลของลูกค้าและผู้ใช้บางส่วนหลุดออกจากการถกเถียง และข้อมูลส่วนบุคคลของพวกเขากลายเป็นต้นทุน
ในบรรดาบริษัทที่ระบุไว้ตรงนี้ ผมคงจะระวังบริษัทที่ตัดสินใจแบบนั้นแล้วผู้นำยังไม่เปลี่ยน
มีการพิสูจน์มาแล้วหลายครั้งว่าบริษัทจำนวนมากไม่ได้ใส่ใจพอที่จะปกป้องลูกค้า และประวัติศาสตร์ก็มักซ้ำรอย
มีคำถามพื้นฐานมากเกี่ยวกับ Firebase: แอปส่วนใหญ่ในบทความนี้ถูกทำขึ้นด้วย JavaScript ฝั่งไคลเอนต์ที่โฮสต์แบบสแตติก โดยไม่มีโค้ดเซิร์ฟเวอร์แบบกำหนดเอง เลยหรือเปล่า?
อยากรู้ว่าหมายถึงแบ็กเอนด์เป็นการตั้งค่า Firebase ที่ Google โฮสต์ให้ 100% ใช่ไหม
ถ้าใช่ ก็ไม่เคยรู้เลยว่าสถาปัตยกรรมแบบนี้กลายเป็นเรื่องแพร่หลายขนาดนี้ในไซต์ที่มีผู้ใช้หลายล้านคน
ถ้าวางโมเดลความปลอดภัยของ API แบบ อนุญาตโดยค่าเริ่มต้น ก็ต้องออกมาแบบนี้อย่างเลี่ยงไม่ได้
น่าเสียดายที่ไลบรารีที่มุ่งเป้าไปยังนักพัฒนา JavaScript มักมีค่าเริ่มต้นที่ไม่ปลอดภัย และ GraphQL ก็ดูเป็นอีกพื้นที่ที่อาจเกิดปัญหาแบบนี้ได้
Firebase ยังมี Firebase Functions ซึ่งเป็นฟังก์ชันที่เรียกได้บนคลาวด์ และโค้ดส่วนนั้นไม่ถูกเปิดเผย
แต่ทั้ง Firestore และ Firebase Realtime Database ต่างก็ต้องให้ผู้ใช้ตั้งกฎความปลอดภัยเอง ไม่เช่นนั้นใครก็อ่านข้อมูลทั้งหมดได้
สิ่งสำคัญคือทำให้เขียนกฎการอนุญาตที่เหมาะสมในแบ็กเอนด์ได้ง่าย
เห็นเรื่องแบบนี้แล้วรู้สึกโชคดีที่เลือกใช้ ตัวจัดการรหัสผ่าน กับบัตรเสมือนไว้ตั้งนานแล้ว
ถึงอย่างนั้นอินเทอร์เน็ตก็น่ากลัวขึ้นเรื่อย ๆ
คนส่วนใหญ่ไม่รู้เลยว่าเว็บเปราะบางแค่ไหน และตัวเองถูกเปิดเผยมากเพียงใด
เพราะ AI agent จะค้นหาช่องโหว่ได้มีประสิทธิภาพกว่าบอตมาก รู้สึกเหมือนมีอนาคตแปลก ๆ รออยู่
ควรใช้ ที่อยู่อีเมลเฉพาะ สำหรับทุกบริการที่สมัคร
จะช่วยจำกัดความเสียหายเมื่อเกิดเหตุ และป้องกันไม่ให้ถูกนำข้อมูลสาธารณะไปเทียบกับบริการอื่นเพื่อเก็บรวบรวมข้อมูลได้
บางครั้งถ้ามีอีเมลอันตรายส่งมาที่อีเมลเฉพาะนั้น ก็อาจรู้ว่าถูกเจาะก่อนผู้ดูแลไซต์เสียอีก
มีใครรู้เพิ่มเติมเกี่ยวกับส่วนที่ว่า “โปรแกรม Python ที่มีเธรดประมาณ 500 เธรดจะเริ่มกินหน่วยความจำเมื่อเวลาผ่านไป” ไหม?
ผมเองก็มี สเครเปอร์ ที่เขียนด้วย Python และมีหลายร้อยเธรด เหมือนจะกินหน่วยความจำมากเหมือนกัน
อยากรู้ว่ามีวิธีเลี่ยงไหม หรือทางแก้เดียวคือต้องเขียนใหม่ด้วยภาษาอื่น
ส่วนตัวชอบใช้โปรเซสมากกว่าเธรด และใช้ worker pool กับ message bus แทน shared memory
วิธีนี้ก็มีข้อเสียและ overhead บ้างเล็กน้อย แต่ทำให้กังวลเรื่องหน่วยความจำน้อยลงมาก
สำหรับ crawler โมเดลแบบโปรเซสดูจะเหมาะกว่า เพราะจำนวนโปรเซสค่อนข้างคงที่และงานของแต่ละโปรเซสเป็นอิสระจากกัน
import multiprocessing as threadingการเขียนใหม่แทบจะเป็นทางแก้เดียวที่ใช้ได้จริง
เป็น use case ที่เหมาะมาก
ทำได้ดีมาก
อยากรู้ว่าสรุปได้อย่างไรว่าจำนวนผู้ใช้ที่ได้รับผลกระทบน่าจะมากกว่านี้จริง ๆ
ดูเผิน ๆ เหมือนบางไซต์ เช่นเว็บพนันหรือ Lead Carrot อาจมี ข้อมูลบัญชีปลอม ปะปนอยู่มากก็ได้
เป็นวิธีที่ทำงานได้ดีเฉพาะกับไซต์ภาษาอังกฤษ
เหตุผลที่บอกว่ามากกว่านั้น เพราะบริการอื่น ๆ ที่ไม่ได้อยู่ในรายการสแกนก็อาจมีช่องโหว่ด้วย