3 คะแนน โดย GN⁺ 2024-03-19 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • การตั้งค่า กฎความปลอดภัยของ 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 จากเว็บไซต์หรือ .js bundle ที่ถูกโหลด แต่เมื่อทำงานที่ประมาณ 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 ความคิดเห็น

 
GN⁺ 2024-03-19
ความคิดเห็นจาก Hacker News
  • ผมทำงานที่ Firebase มานาน และปัญหาเรื่อง กฎความปลอดภัย ก็รบกวนผลิตภัณฑ์นี้มาตลอด
    เคยลองหลายแนวทาง เช่น กฎเริ่มต้นที่หมดอายุอัตโนมัติ การเพิ่มการให้ความรู้ แต่สุดท้ายก็ยังเห็นฐานข้อมูลจำนวนมากที่ไม่ปลอดภัยอยู่ดี
    เหตุผลค่อนข้างซับซ้อน แต่กฎความปลอดภัยแบบ Firebase ยังเป็นแนวคิดที่ไม่คุ้นเคย และนักพัฒนาใหม่ที่เพิ่มข้อมูลเข้าไปในตำแหน่งเดิมก็มักไม่แก้กฎให้สอดคล้องกับข้อกำหนดด้านความเป็นส่วนตัวของข้อมูลที่เปลี่ยนไป
    อีกอย่างคือ “ความปลอดภัยจากความคลุมเครือ” ที่แบ็กเอนด์ที่แต่ละคนทำเองเคยมีนั้นหายไป ทำให้การสแกนในวงกว้างทำได้ง่ายขึ้น
    โดยเฉพาะกฎของ Realtime Database นั้นเขียนยากและขยายต่อได้ไม่ดี แต่การสแกนอัตโนมัติมักมองหาแค่ข้อมูลที่เปิดอยู่ ดังนั้นถ้าดีกว่า read write true เพียงเล็กน้อยก็พอจะกันได้
    ในทางเทคนิค แนวทางของ Firebase เองไม่ได้ผิด แต่เพราะแทบจะเป็นแบ็กเอนด์รายเดียวที่ใช้โมเดลที่เน้นข้อมูลที่จัดเก็บกับกฎความปลอดภัย จึงเสี่ยงต่อความเข้าใจผิด การใช้งานผิด และเหตุการณ์แบบนี้ได้ง่าย

    • พูดตรง ๆ โมเดลที่ให้ฟรอนต์เอนด์เขียนข้อมูลลงฐานข้อมูลโดยตรงนั้นดูน่าสงสัยอยู่เสมอ แม้จะมี กฎความปลอดภัย ก็ตาม
      ในแบ็กเอนด์ การตรวจสอบความถูกต้องและกฎความปลอดภัยดูเหมือนเป็นส่วนหนึ่งของสเปก แต่กฎความปลอดภัยของ Firebase เป็นกระบวนการแยกต่างหาก จึงลืมได้ง่าย และต้องประเมินใหม่ทุกครั้งที่สร้างฟีเจอร์ใหม่
    • ผมติดต่อผ่านช่องทางซัพพอร์ตของ Google เพื่อขอให้ช่วยหรือให้แจ้งปัญหากับเว็บไซต์เหล่านั้นได้ แต่ได้รับคำตอบแค่ว่าถ้าต้องการจะสร้าง คำขอฟีเจอร์ แทนให้
      ถ้าจะดึงความสนใจจากคนที่แจ้งเจ้าของโปรเจกต์ได้ คงต้อง escalate ภายใน Firebase ไปค่อนข้างสูง
    • เมื่อดู https://firebase.google.com/docs/rules/basics ก็สงสัยว่า โหมดความปลอดภัยแบบง่าย ที่ให้เลือกเฉพาะเทมเพลตกฎความปลอดภัยที่กำหนดไว้ล่วงหน้าจะใช้งานได้จริงไหม
      เช่น เทมเพลตในบทความอย่าง “เฉพาะเจ้าของคอนเทนต์เข้าถึงได้” หรือ “การเข้าถึงตามคุณสมบัติและตามบทบาท” จะครอบคลุมแพตเทิร์นของแอปส่วนใหญ่ได้หรือไม่ หรือจริง ๆ แล้วยังต้องใช้กฎแบบปรับแต่งเองจำนวนมาก
      ปัญหาใหญ่ของการเขียนกฎความปลอดภัยคือความผิดพลาดแทบทุกอย่างกลายเป็นปัญหาความปลอดภัย จึงไม่อยากไปแตะถ้าไม่จำเป็น
      ถ้ากฎล็อกแน่นเกินไป แอปจะไม่ทำงานและเห็นได้ทันที แต่ถ้าเปิดกว้างเกินไป มักไม่เห็นชัดจนกว่าจะลองเจาะการเข้าถึงที่เกินสิทธิ์เอง
      ในเรื่องนี้ ก็น่าคิดถึงวิธีบังคับให้นักพัฒนาเขียนเคสทดสอบตัวอย่างการปฏิเสธการเข้าถึงสำหรับกฎความปลอดภัยแต่ละข้อด้วย
    • มีทริกง่าย ๆ อย่างหนึ่งที่ช่วยเราได้มาก: transpiler กฎ ชื่อ fireplan จะเพิ่มกฎเริ่มต้น "$other": {".read": false, ".write": false} ให้กับทุก property
      ด้วยเหตุนี้ ฟิลด์ใหม่ต้องถูกเพิ่มอย่างชัดเจน ทำให้แทบเป็นไปไม่ได้ที่ค่าใหม่จะ “สืบทอด” กฎเดิมโดยไม่รู้ตัว
      เราใช้ Firebase มานานกว่า 10 ปีแล้ว จึงไม่รู้ว่าเครื่องมือกฎรุ่นใหม่ทำแบบนี้ด้วยหรือไม่
      สิ่งที่จะช่วยได้จริง ๆ คือการรองรับพื้นฐานสำหรับการเปลี่ยนชื่อฟิลด์หรือเปลี่ยนโครงสร้างข้อมูลในสถานการณ์ที่มีไคลเอนต์หลายเวอร์ชันที่ควบคุมได้ยาก วิธีทดสอบกฎแบบเบา ๆ โดยไม่ต้องเปิดฐานข้อมูล และข้อมูลดีบักที่ดีกว่าเมื่อกฎล้มเหลวในสภาพแวดล้อม production
      ทุกครั้งที่ล้มเหลว ควรบันทึกค่าทั้งหมดที่กฎเข้าถึงไว้ด้วย จึงจะดีบักความล้มเหลวชั่วคราวที่เกิดจากข้อมูลที่เปลี่ยนแปลงได้
    • ผมค่อนข้างปกป้อง Firebase และ Firestore มาตลอด แต่เห็นด้วยกับทั้งหมดข้างต้น
      นี่คือ โมเดลเชิงแนวคิด ที่ยังอธิบายไม่เพียงพอ
      ในโปรเจกต์ เราจะบอกว่าแต่ละ 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 ต่างก็ต้องให้ผู้ใช้ตั้งกฎความปลอดภัยเอง ไม่เช่นนั้นใครก็อ่านข้อมูลทั้งหมดได้
    • ดูเหมือนเป็นการจัดวางที่ค่อนข้างสุดโต่ง แต่ถ้าเขียน กฎการอนุญาต ที่เหมาะสมในสคีมา SQL ของแบ็กเอนด์ ก็ทำงานได้
      สิ่งสำคัญคือทำให้เขียนกฎการอนุญาตที่เหมาะสมในแบ็กเอนด์ได้ง่าย
  • เห็นเรื่องแบบนี้แล้วรู้สึกโชคดีที่เลือกใช้ ตัวจัดการรหัสผ่าน กับบัตรเสมือนไว้ตั้งนานแล้ว
    ถึงอย่างนั้นอินเทอร์เน็ตก็น่ากลัวขึ้นเรื่อย ๆ
    คนส่วนใหญ่ไม่รู้เลยว่าเว็บเปราะบางแค่ไหน และตัวเองถูกเปิดเผยมากเพียงใด

    • คิดว่าต่อไปจะแย่ลงอีก
      เพราะ AI agent จะค้นหาช่องโหว่ได้มีประสิทธิภาพกว่าบอตมาก รู้สึกเหมือนมีอนาคตแปลก ๆ รออยู่
    • ยิ่งเวลาผ่านไป บริการต่าง ๆ ก็ทำให้การสร้างเว็บไซต์ง่ายขึ้นและ abstract สิ่งต่าง ๆ มากขึ้น จนทำให้นักพัฒนาไม่รู้ว่าต้องตั้งค่าอะไรบ้าง
    • ตัวจัดการรหัสผ่านอย่างเดียวไม่พอ
      ควรใช้ ที่อยู่อีเมลเฉพาะ สำหรับทุกบริการที่สมัคร
      จะช่วยจำกัดความเสียหายเมื่อเกิดเหตุ และป้องกันไม่ให้ถูกนำข้อมูลสาธารณะไปเทียบกับบริการอื่นเพื่อเก็บรวบรวมข้อมูลได้
      บางครั้งถ้ามีอีเมลอันตรายส่งมาที่อีเมลเฉพาะนั้น ก็อาจรู้ว่าถูกเจาะก่อนผู้ดูแลไซต์เสียอีก
  • มีใครรู้เพิ่มเติมเกี่ยวกับส่วนที่ว่า “โปรแกรม Python ที่มีเธรดประมาณ 500 เธรดจะเริ่มกินหน่วยความจำเมื่อเวลาผ่านไป” ไหม?
    ผมเองก็มี สเครเปอร์ ที่เขียนด้วย Python และมีหลายร้อยเธรด เหมือนจะกินหน่วยความจำมากเหมือนกัน
    อยากรู้ว่ามีวิธีเลี่ยงไหม หรือทางแก้เดียวคือต้องเขียนใหม่ด้วยภาษาอื่น

    • ทำด้วย Python ก็ได้ แต่ต้องลงลึกว่า reference counting ของ Python โต้ตอบกับเธรดอย่างไร
      ส่วนตัวชอบใช้โปรเซสมากกว่าเธรด และใช้ worker pool กับ message bus แทน shared memory
      วิธีนี้ก็มีข้อเสียและ overhead บ้างเล็กน้อย แต่ทำให้กังวลเรื่องหน่วยความจำน้อยลงมาก
      สำหรับ crawler โมเดลแบบโปรเซสดูจะเหมาะกว่า เพราะจำนวนโปรเซสค่อนข้างคงที่และงานของแต่ละโปรเซสเป็นอิสระจากกัน
    • import multiprocessing as threading
    • ไม่รู้ปัญหาที่แน่ชัด แต่พูดตรง ๆ Python ไม่ใช่ภาษาที่เหมาะกับงานแบบนี้
      การเขียนใหม่แทบจะเป็นทางแก้เดียวที่ใช้ได้จริง
    • กรณีนี้ควรใช้ asyncio
      เป็น use case ที่เหมาะมาก
  • ทำได้ดีมาก
    อยากรู้ว่าสรุปได้อย่างไรว่าจำนวนผู้ใช้ที่ได้รับผลกระทบน่าจะมากกว่านี้จริง ๆ
    ดูเผิน ๆ เหมือนบางไซต์ เช่นเว็บพนันหรือ Lead Carrot อาจมี ข้อมูลบัญชีปลอม ปะปนอยู่มากก็ได้

    • จากการตรวจหลายไซต์ด้วยตนเอง พบว่าสแกนอัตโนมัติใช้วิธีดูประเภทข้อมูลที่รู้จัก เช่นหมายเลขโทรศัพท์ จากชื่อตัวแปร จึงระบุ ข้อมูลส่วนบุคคลที่ไม่ใช่ภาษาอังกฤษ ได้ไม่ค่อยดี
      เป็นวิธีที่ทำงานได้ดีเฉพาะกับไซต์ภาษาอังกฤษ
    • ยืนยันแล้วว่าข้อมูลของเว็บพนันไม่ใช่ของปลอม แต่ฝั่ง Lead ไม่แน่ใจ
      เหตุผลที่บอกว่ามากกว่านั้น เพราะบริการอื่น ๆ ที่ไม่ได้อยู่ในรายการสแกนก็อาจมีช่องโหว่ด้วย