สรุปสั้น

บริษัท Mozilla ตัดสินใจทิ้งกุญแจเข้ารหัสที่อยู่เบื้องหลังไฟล์ดาวน์โหลด Firefox และ Thunderbird สำหรับ Linux หลังพบว่ากุญแจฉบับที่ไม่ได้เข้ารหัสถูกคอมมิตเข้าไปในคลังโค้ดส่วนตัวแห่งหนึ่งของบริษัทเองโดยไม่ได้ตั้งใจ กุญแจตัวนี้คือสิ่งที่ผู้ใช้หรือผู้ดูแลแพ็กเกจของ Linux distribution ใช้ยืนยันว่าไฟล์ tarball ของ Firefox ที่ดาวน์โหลดมานั้นมาจาก Mozilla จริงและไม่ถูกดัดแปลงระหว่างทาง จนถึงตอนนี้ยังไม่มีสัญญาณว่าคนนอกบริษัทเข้าถึงกุญแจดังกล่าว เพราะคลังโค้ดเป็นแบบส่วนตัว บริษัทระบุว่าการตรวจสอบบันทึกเท่าที่มีอยู่ไม่พบร่องรอยการเข้าถึงโดยไม่ได้รับอนุญาต และทุกคนที่เห็นกุญแจนั้นล้วนมีสิทธิ์เข้าถึงอยู่แล้วโดยชอบ แต่ Mozilla เลือกเพิกถอนกุญแจทิ้งอยู่ดี

การตัดสินใจนี้มีต้นทุนสำหรับคนที่ตรวจสอบไฟล์ที่ดาวน์โหลดมาจริงจัง เพราะเมื่อผู้ใช้นำเข้าใบเพิกถอนแล้ว ไฟล์ที่เคยเซ็นด้วยกุญแจเดิมจะตรวจสอบลายเซ็นไม่ผ่านทันที ซึ่งครอบคลุมไฟล์ Firefox และ Thunderbird รุ่นเก่าด้วย ไม่ใช่เฉพาะรุ่นที่จะออกในอนาคต ผู้ใช้ส่วนใหญ่ไม่ต้องทำอะไร แต่มีสองกลุ่มที่ต้องลงมือคือคนที่ตรวจลายเซ็นด้วยตัวเอง ซึ่งต้องนำเข้ากุญแจใหม่พร้อมใบเพิกถอนของกุญแจเก่า และคนที่ติดตั้ง Firefox จากแพ็กเกจ RPM ของ Mozilla ซึ่งอาจเจอการอัปเดตล้มเหลวและต้องสลับกุญแจด้วยมือ ส่วนผู้ใช้ Debian และ Ubuntu ที่ใช้คลัง APT ไม่ได้รับผลกระทบ เพราะใช้กุญแจคนละตัวและรูปแบบ .deb ไม่อยู่ในรายการที่กระทบ

รายละเอียดข่าว

เว็บไซต์ The Hacker News รายงานเมื่อวันที่ 11 สิงหาคม 2569 ว่า Mozilla ได้เพิกถอนกุญแจเข้ารหัสที่ใช้เซ็นไฟล์ดาวน์โหลดของ Firefox และ Thunderbird บน Linux หลังสำเนาของกุญแจแบบไม่เข้ารหัสถูกคอมมิตเข้าคลังโค้ดส่วนตัวของบริษัทโดยผิดพลาด ซับคีย์ตัวใหม่ที่เผยแพร่เมื่อวันจันทร์มีลายนิ้วมือ 827E 6586 0867 9618 CD34 9F93 678E 455D 7676 7AA3 และมีอายุถึงวันที่ 5 สิงหาคม 2571

มาตรฐาน OpenPGP เปิดให้เจ้าของกุญแจแนบเหตุผลที่เครื่องอ่านได้ไว้กับการเพิกถอน และ RFC 4880 อธิบายไว้ชัดว่าทำไมเรื่องนี้จึงสำคัญ กล่าวคือกุญแจที่ถูกแทนที่หรือปลดระวางตามอายุจะยังทำให้ลายเซ็นในอดีตใช้ตรวจสอบได้ต่อไป ขณะที่กุญแจซึ่งถูกเพิกถอนเพราะถูกเจาะจะทำให้ลายเซ็นทุกฉบับที่กุญแจนั้นเคยสร้างกลายเป็นสิ่งที่เชื่อถือไม่ได้ทั้งหมด The Hacker News ถอดรหัสใบเพิกถอนที่เผยแพร่มาพร้อมกุญแจใหม่ แล้วพบว่าเป็นเหตุผลรหัส 2 ซึ่งหมายถึง “วัสดุกุญแจถูกเจาะ” สร้างขึ้นเมื่อวันที่ 6 สิงหาคม 2569 เวลา 11:14 UTC พร้อมข้อความกำกับว่า “เราไม่เชื่อถือกุญแจนี้อีกต่อไป” ขณะที่คำอธิบายเหตุการณ์ของ Mozilla เองไม่ได้พูดตรง ๆ ว่ากุญแจถูกขโมยไป

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

การสลับกุญแจครั้งนี้ยังเกิดขึ้นเร็วกว่ากำหนดราวเจ็ดเดือน โดยปกติบริษัทหมุนซับคีย์ตัวนี้ทุกประมาณสองปีเพื่อป้องกันการรั่วไหลที่อาจไม่มีใครรู้ตัว ซับคีย์ที่ถูกเพิกถอนคือ 09BE ED63 F346 2A2D FFAB 3B87 5ECB 6497 C1A2 0256 ซึ่งประกาศใช้เมื่อเดือนเมษายน 2568 และเดิมมีอายุถึงเดือนมีนาคม 2570 เมื่อตรวจกุญแจสาธารณะฉบับเต็มที่เก็บอยู่ในคลังเซ็นของ Mozilla เองจะพบซับคีย์สำหรับเซ็นรุ่นเก่าอีกห้าตัวย้อนไปถึงปี 2558 ซึ่งทุกตัวปลดระวางด้วยการหมดอายุตามกำหนด ครั้งนี้จึงเป็นการเพิกถอนครั้งแรกของกุญแจชุดนี้

สิ่งที่ Mozilla ยังไม่ได้บอกคือคลังโค้ดใดที่เก็บกุญแจไว้ กุญแจอยู่ตรงนั้นนานแค่ไหน และเรื่องถูกค้นพบได้อย่างไร อีกทั้งไม่ได้อธิบายรายละเอียดของมาตรการป้องกันที่บริษัทบอกว่าได้เพิ่มเข้าไปแล้ว ส่วนคลัง APT ที่ให้บริการผู้ใช้ Debian และ Ubuntu นั้นบริษัทไม่ได้พูดถึงทั้งในทางยืนยันหรือปฏิเสธ แต่คลังดังกล่าวใช้กุญแจคนละตัวและรูปแบบ .deb ไม่อยู่ในรายการที่ได้รับผลกระทบ ทั้งนี้การเปิดเผยเรื่องนี้เกิดขึ้นหนึ่งสัปดาห์หลังผู้โจมตียึดบัญชี GitHub ที่ดูแลแพ็กเกจ npm ชื่อ keyv และ cacheable แล้วปล่อยเวิร์มที่ออกแบบมาเก็บเกี่ยวข้อมูลคลังโค้ด รีจิสทรี คลาวด์ และกุญแจส่วนตัวจากเครื่องนักพัฒนาและระบบ CI

ผลของการเพิกถอนในเชิงเทคนิค

หัวใจของเรื่องนี้อยู่ที่ความต่างระหว่างการหมุนกุญแจกับการเพิกถอนเพราะถูกเจาะ ถ้า Mozilla เลือกใส่เหตุผลว่ากุญแจถูกแทนที่หรือปลดระวาง ลายเซ็นเก่าทั้งหมดจะยังใช้ตรวจสอบได้ตามปกติ แต่เมื่อใบเพิกถอนระบุรหัส 2 ที่แปลว่าวัสดุกุญแจถูกเจาะ ซอฟต์แวร์ GPG จะถือว่าลายเซ็นทุกฉบับที่ซับคีย์นั้นเคยสร้างเป็นสิ่งที่เชื่อถือไม่ได้ ผู้ที่นำเข้าใบเพิกถอนแล้วย้อนไปตรวจไฟล์ Firefox รุ่นเก่าที่เก็บไว้จึงจะเห็นการตรวจสอบล้มเหลว ทั้งที่ไฟล์นั้นอาจไม่ได้ถูกแตะต้องเลย

ในฝั่ง RPM ผลกระทบเป็นรูปธรรมกว่านั้น dnf บนบางดิสทริบิวชันจะจัดการเปลี่ยนกุญแจให้เอง โดยดึงกุญแจใหม่มาในการอัปเดตครั้งถัดไปแล้วถามผู้ใช้ให้ยืนยันลายนิ้วมือ แต่บนบางระบบจะล้มเหลวไปเลย โดยรายงานว่าการนำเข้ากุญแจไม่ช่วยอะไร หรือว่ากุญแจของคลังที่ติดตั้งอยู่ไม่ตรงกับแพ็กเกจ ทางแก้คือต้องถอนกุญแจเก่าออกก่อน เพราะคำสั่ง rpm –import สามารถรายงานว่าสำเร็จได้ทั้งที่กุญแจเก่ายังค้างอยู่ในระบบ โดยลำดับคำสั่งคือ sudo rpm -e --allmatches gpg-pubkey-14f26682d0916cdd81e37b6d61b7b526d98f0353 ตามด้วย sudo rpm --import https://packages.mozilla.org/rpm/firefox/signing-key.gpg แล้วจึง sudo dnf clean all ส่วน Thunderbird ไม่มีแพ็กเกจ RPM อย่างเป็นทางการ ขั้นตอนนี้จึงไม่เกี่ยวข้อง และผู้ใช้ openSUSE ให้รันสองคำสั่ง rpm เดียวกันแล้วตามด้วย zypper refresh

ผลกระทบ

สำหรับผู้ใช้ทั่วไปที่ติดตั้ง Firefox ผ่านคลังแพ็กเกจของดิสทริบิวชันหรือผ่าน Snap/Flatpak เรื่องนี้แทบไม่มีผลอะไร แต่สำหรับองค์กรที่มีกระบวนการตรวจสอบลายเซ็นก่อนนำซอฟต์แวร์เข้าใช้งานภายใน การเพิกถอนด้วยเหตุผล “ถูกเจาะ” ทำให้ไฟล์ที่เก็บไว้ในคลังภายในทั้งหมดกลายเป็นไฟล์ที่พิสูจน์ที่มาไม่ได้ในชั่วข้ามคืน ทีมที่ใช้การตรวจลายเซ็นเป็นเงื่อนไขในไปป์ไลน์การติดตั้งอัตโนมัติอาจเจอกระบวนการหยุดชะงักโดยไม่ทราบสาเหตุ และผู้ดูแลแพ็กเกจของ Linux distribution ที่ตรวจ tarball ต้นทางก็ต้องอัปเดตชุดกุญแจของตัวเองตามไปด้วย

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

คำแนะนำ

ผู้ที่ตรวจสอบลายเซ็นไฟล์ด้วยตัวเองควรนำเข้ากุญแจสาธารณะตัวใหม่จาก Mozilla พร้อมใบเพิกถอนของกุญแจเดิม แล้วตรวจสอบว่าลายนิ้วมือตรงกับ 827E 6586 0867 9618 CD34 9F93 678E 455D 7676 7AA3 ก่อนนำไปใช้จริง หากมีไฟล์ติดตั้งรุ่นเก่าที่เก็บไว้ในคลังภายในองค์กร ควรยอมรับว่าไฟล์เหล่านั้นจะตรวจลายเซ็นไม่ผ่านอีกต่อไปและวางแผนดาวน์โหลดใหม่จากต้นทางแทนการพยายามข้ามการตรวจสอบ

ผู้ใช้แพ็กเกจ RPM ที่พบว่าอัปเดตล้มเหลว ให้ถอนกุญแจเก่าออกด้วย rpm -e –allmatches ตามด้วยการนำเข้ากุญแจใหม่จาก packages.mozilla.org แล้วล้างแคชด้วย dnf clean all โดยผู้ใช้ openSUSE ให้ใช้ zypper refresh แทนขั้นตอนสุดท้าย ส่วนผู้ใช้ Debian และ Ubuntu ที่ติดตั้งผ่านคลัง APT ของ Mozilla ไม่ต้องทำอะไรเพราะใช้กุญแจคนละตัว สำหรับองค์กรทั่วไป บทเรียนที่นำไปใช้ได้ทันทีคือการสแกนคลังโค้ดทั้งหมดเพื่อหาความลับที่ถูกคอมมิตโดยไม่ตั้งใจ โดยเฉพาะกุญแจสำหรับเซ็นและกุญแจส่วนตัว และตั้งกฎ pre-commit hook สกัดไฟล์ประเภทนี้ตั้งแต่ต้นทาง เพราะการที่คลังเป็นแบบส่วนตัวไม่ใช่เหตุผลเพียงพอที่จะไม่ต้องหมุนความลับเมื่อเกิดเหตุ

แหล่งอ้างอิง