1 คะแนน โดย GN⁺ 2025-03-24 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • แบ็กดอร์ xz ที่ค้นพบในเดือนมีนาคม 2024 อาจนำไปสู่ การรันโค้ดจากระยะไกล ในสภาพแวดล้อม sshd ที่ได้รับผลกระทบ และกรณีของ NixOS แสดงให้เห็นว่าบิลด์ที่ทำซ้ำได้สามารถเผยการดัดแปลงซัพพลายเชนได้แบบเชิงกล
  • องค์ประกอบที่เป็นอันตรายไม่ได้ซ่อนอยู่ใน Git repository ทั้งหมดของ xz แต่อยู่ใน release tarball ที่ผู้ดูแลจัดทำให้ ของเวอร์ชัน 5.6.0 และ 5.6.1 และระหว่างการบิลด์จะสร้าง shell script กับ object file จากไฟล์ทดสอบ .xz ปลอม
  • การโจมตีใช้ ifunc ของ glibc เพื่อรันโค้ดตอนโหลด liblzma และมุ่งเป้าไปที่สภาพแวดล้อมตระกูล Debian/Fedora ที่ sshd มี dependency แบบถ่ายทอดไปยัง liblzma ผ่าน libsystemd
  • โดยปกติ NixOS มักชอบใช้ source archive ที่ GitHub สร้างให้อัตโนมัติ แต่เนื่องจาก xz อยู่ในขั้นตอน bootstrap ของ nixpkgs จึงต้องเชื่อถือ tarball ของผู้ดูแลเพื่อหลีกเลี่ยง dependency แบบวนรอบกับ autoconf
  • แนวทางป้องกันที่เสนอคือ หลัง bootstrap ให้บิลด์ xz ใหม่จากซอร์ส GitHub แล้วนำไปเปรียบเทียบกับผลลัพธ์จาก tarball เดิม และเมื่อเปิดใช้เงื่อนไขดังกล่าวก็พบความต่างของขนาด liblzma.so รวมถึงการเพิ่มสัญลักษณ์ _get_cpuid

วิธีที่แบ็กดอร์ xz แฝงตัวเข้ามา

  • xz เป็นซอฟต์แวร์บีบอัดและคลายบีบอัดที่มักใช้เมื่อแตก source tarball ในเส้นทางสำคัญของ Linux distribution
  • ในเดือนมีนาคม 2024 มีการค้นพบแบ็กดอร์ใน xz และผู้ดูแลที่เป็นอันตรายชื่อ Jia Tan ใช้เวลาราว 3 ปีในการสร้างความไว้วางใจและได้สิทธิ์ push เข้า repository จากนั้นค่อย ๆ ใส่โค้ดที่ทำให้เข้าใจยากปะปนไปกับ contribution ที่ถูกต้องตามปกติ
  • Andres Freund ตรวจสอบปัญหา performance ของ ssh ที่ช้าลง 500ms บนเครื่อง Debian unstable หลายเครื่อง ไล่ตามไปจนถึง liblzma แล้วระบุและจัดทำเอกสารเกี่ยวกับแบ็กดอร์ได้
  • เป้าหมายของแบ็กดอร์คือการ hijack ssh เพื่อให้ผู้โจมตีสามารถรันคำสั่งใด ๆ บนเครื่องเหยื่อเมื่อเข้าสู่ระบบด้วย RSA key เฉพาะ

tarball ที่เป็นอันตรายและ object ที่สร้างระหว่างบิลด์

  • องค์ประกอบที่เป็นอันตรายไม่ได้ถูกใส่โดยตรงไว้ในโค้ดทั้งหมดของ Git repository ของ xz แต่อยู่ใน release tarball ของ xz 5.6.0 และ 5.6.1 ที่ Jia Tan บิลด์ เซ็น และเผยแพร่
  • ไฟล์ .xz สำหรับทดสอบบางไฟล์ใน Git repository มี machine code ซ่อนอยู่ และใน release tarball มีการเพิ่มการเปลี่ยนแปลงที่พรางไว้เพื่อดึงสิ่งนั้นออกมา
  • โดยเฉพาะการเปลี่ยนแปลงใน m4/build-to-host.m4 ซึ่งดูภายนอกเหมือนไม่มีพิษภัยและมีคอมเมนต์ประกอบ แต่จริง ๆ แล้วซ่อนชุดคำสั่งสำหรับถอดรหัสและคลายการพรางของไฟล์ทดสอบ .xz ปลอมหลายไฟล์
  • ผลลัพธ์ของกระบวนการนี้มีสองอย่าง
    • shell script ที่รันระหว่างการบิลด์ xz
    • binary object file ที่เป็นอันตราย
  • shell script ที่รันระหว่างการบิลด์มีสองบทบาท
    • ตรวจสอบเงื่อนไขการทำงานของแบ็กดอร์ เช่น Linux distribution บางรายการ ความสามารถของ glibc และการติดตั้ง ssh
    • แก้ไข object ปกติ liblzma_la-crc64_fast.o ให้ใช้สัญลักษณ์ _get_cpuid ของ object file แบ็กดอร์
  • xz script analysis ของ Russ Cox อธิบายรายละเอียดกระบวนการสร้างทรัพยากรที่เป็นอันตรายระหว่างบิลด์

การ hijack ifunc ที่นำไปสู่ sshd

  • ในโปรแกรมที่ลิงก์แบบ dynamic ขณะรัน dynamic loader จะโหลด shared library เข้า memory และเติม address ของ symbol ลงใน Global Offset Table(GOT)
  • ifunc ของ glibc เป็นความสามารถสำหรับเลือก implementation หนึ่งจากหลาย implementation ของฟังก์ชันเดียวกันในช่วง dynamic loading และแบ็กดอร์ xz ใช้สิ่งนี้เป็นเส้นทางรันโค้ดที่เป็นอันตราย
  • ssh ใน distribution บางรายการ เช่น Debian และ Fedora ลิงก์กับ libsystemd เพื่อรองรับการแจ้งเตือนของ systemd และ libsystemd ก็ลิงก์กับ liblzma อีกทอดหนึ่ง
    • ในสภาพแวดล้อมนี้ sshd จึงมี dependency แบบถ่ายทอดไปยัง liblzma
  • เมื่อรัน sshd dynamic loader จะโหลด libsystemd และ liblzma และถ้ามีแบ็กดอร์ติดตั้งอยู่ โค้ดที่เป็นอันตรายจะถูกรันระหว่างการโหลด liblzma
  • แบ็กดอร์ทำให้ ifunc resolver เรียกสัญลักษณ์ _get_cpuid ที่เป็นอันตราย และแก้ไข GOT ซึ่งยังไม่เป็น read-only เพื่อเปลี่ยน address ของ RSA_public_decrypt ให้เป็นฟังก์ชันที่เป็นอันตราย
  • สามารถดู การวิเคราะห์โดยละเอียด ของ Securelist และ บทความวิจัย ที่สรุป attack vector และมาตรการบรรเทาเป็นข้อมูลอ้างอิงได้

ซอร์สที่เชื่อถือได้และข้อจำกัด bootstrap ของ NixOS

  • การโจมตีนี้เกิดผลได้เพราะหลาย distribution บิลด์ xz จาก tarball ที่ผู้ดูแลจัดทำให้ แทนที่จะใช้ซอร์สต้นฉบับจาก Git forge
  • workflow แบบ tarball มีเหตุผลทั้งทางประวัติศาสตร์และทางปฏิบัติ
    • เป็นแนวทางของ Linux distribution ยุคแรก ๆ ที่เก่ากว่า git
    • เก็บรักษาสถานะของซอร์ส ณ เวลาที่ release ในรูป archive ที่บรรจุครบในตัวเอง
    • ลดภาระการบิลด์ได้ด้วยการรวมผลลัพธ์ขั้นกลาง เช่น manpage และ configure script
    • ได้ประสิทธิภาพด้านพื้นที่จัดเก็บจากการบีบอัด
  • จากมุมมองด้านความปลอดภัย เมื่อเป็นไปได้ทางเทคนิค ควรบิลด์จากซอร์สที่ผ่านการรับรองโดยฝ่ายที่เชื่อถือได้มากที่สุด
    • ถ้าเป็นโปรเจกต์ที่พัฒนาบน GitHub ก็สามารถใช้ archive ที่ GitHub สร้างให้อัตโนมัติสำหรับแต่ละ release ได้
    • ตรรกะเดียวกันนี้ใช้ได้กับแพลตฟอร์มบุคคลที่สามที่เชื่อถือได้ เช่น Codeberg, SourceHut และ GitLab
  • NixOS ใช้โมเดลจัดการแพ็กเกจแบบ functional และแพ็กเกจกำหนดสูตรการบิลด์ด้วย Nix expression
  • ผู้ดูแล NixOS มีวัฒนธรรมในการใช้ source archive ที่ GitHub สร้างให้อัตโนมัติผ่าน fetchFromGitHub เมื่อทำได้ แต่แพ็กเกจ xz ใช้ fetchurl เพื่อดึง tarball ของผู้ดูแลที่อัปโหลดด้วยตนเอง
  • เหตุผลคือ xz รวมอยู่ในขั้นตอน bootstrap ของ nixpkgs
    • bootstrap คือกระบวนการที่ทำให้สามารถบิลด์แพ็กเกจทั้งหมดของ nixpkgs ใหม่จากชุด seed binary ขนาดเล็กได้
    • stdenv คือสภาพแวดล้อมคอมไพล์พื้นฐานที่แพ็กเกจอื่นใช้
    • stdenv พึ่งพา xz ตอน runtime และแพ็กเกจอย่าง coreutils ต้องใช้ xz เพื่อแตก source archive .tar.xz
  • การบิลด์ xz จากซอร์ส GitHub ต้องใช้ autoconf เพื่อสร้าง configure script แต่ autoconf เองก็พึ่งพา xz
    • tarball ที่ผู้ดูแลจัดทำให้มี configure script สร้างไว้แล้ว จึงตัดวงจร dependency นี้ได้
    • ดังนั้น ณ จุดที่ xz ถูกบิลด์ในกราฟของ nixpkgs จึงใช้ source archive จาก GitHub ได้ยากและต้องเชื่อถือ tarball ของผู้ดูแล

เปรียบเทียบการลู่เข้าของผลลัพธ์ แทนการเปรียบเทียบซอร์ส

  • วิธีเปรียบเทียบว่า tarball ของผู้ดูแลกับ source tarball จาก GitHub เหมือนกันหรือไม่ดูเหมือนเป็นธรรมชาติ แต่ในทางปฏิบัติไม่ค่อยเหมาะ
  • Daniel Stenberg อธิบายว่าการที่ release tarball ต่างจากซอร์สนั้นเป็นคุณสมบัติอย่างหนึ่ง
    • สามารถรวมผลลัพธ์ขั้นกลาง เช่น manpage และ configure script ไว้ใน tarball ได้
    • มีประโยชน์เป็นพิเศษเมื่อ distribution ต้องการหลีกเลี่ยง dependency กับ autoconf
  • จากมุมมองด้านความปลอดภัยซัพพลายเชน ความยืดหยุ่นเช่นนี้กลายเป็นภาระที่ต้องเชื่อถือว่าผู้ดูแลซื่อสัตย์
  • บิลด์ที่ทำซ้ำได้ คือคุณสมบัติที่เมื่อบิลด์สองครั้งภายใต้เงื่อนไขเดียวกันแล้วได้ผลลัพธ์เหมือนกันในระดับบิต
  • กลุ่ม reproducible-builds มีเป้าหมายทำให้แพ็กเกจมากที่สุดเท่าที่เป็นไปได้สามารถทำซ้ำได้ และ Reproducible Builds: Increasing the Integrity of Software Supply Chains กล่าวถึงสิ่งนี้ในฐานะคุณสมบัติที่เพิ่มความน่าเชื่อถือให้การแจกจ่าย binary artifact
  • แนวทางทำให้การสร้าง tarball เองทำซ้ำได้ถูกโปรเจกต์ PostgreSQL นำไปใช้
    • ผู้ใช้สามารถตรวจสอบได้อย่างอิสระว่า tarball ของผู้ดูแลถูกสร้างจากซอร์สต้นฉบับอย่างซื่อสัตย์หรือไม่
    • อย่างไรก็ตาม เนื่องจาก upstream project maintainer ต้องเป็นผู้ implement ความเร็วในการนำไปใช้ในชุมชน FOSS จึงอาจช้า

ขั้นตอนตรวจจับที่เสนอใน NixOS

  • หาก xz ทำซ้ำได้ในระดับบิต และ tarball ของผู้ดูแลไม่มีการเปลี่ยนแปลงที่ส่งผลต่อกระบวนการบิลด์ การบิลด์จาก tarball GitHub และการบิลด์จาก tarball ของผู้ดูแลควรให้ผลลัพธ์เดียวกัน
  • วิธีที่เสนอคือบิลด์ xz อีกครั้งหลัง bootstrap โดยครั้งนี้ใช้ source archive จาก GitHub ผ่าน fetchFromGitHub แล้วนำไปเปรียบเทียบกับผลลัพธ์ xz จากขั้นตอน bootstrap เดิม
  • ตัวอย่าง implementation คือวาง after-bootstrap.nix ไว้ใต้ pkgs/tools/compression/xz และบิลด์ xz 5.6.1 จากซอร์ส GitHub
    • tarball ของผู้ดูแลมี configure script อยู่แล้ว แต่การบิลด์จากซอร์ส GitHub ต้องใช้ autoconf, libtool, automake ฯลฯ เพื่อรัน ./autogen.sh
  • เพิ่ม compareArtifacts เป็นขั้นตอนเปรียบเทียบ เพื่อเปรียบเทียบ liblzma.so ในตอนท้ายของบิลด์
    • ในตัวอย่างเปรียบเทียบเฉพาะ liblzma.so ซึ่งเป็นไฟล์ที่แบ็กดอร์แก้ไข แต่สามารถขยายให้ครอบคลุมผลลัพธ์ binary และ library ทั้งหมดได้
  • ใน revision master ปกติ บิลด์ xz-after-bootstrap สำเร็จ และผลลัพธ์ทั้งสองเหมือนกัน
  • ใน revision c53bbe3 ที่มีแบ็กดอร์ ตอนแรกดูเหมือนว่ายังเหมือนกัน
    • บน NixOS แบ็กดอร์ไม่ถูกเปิดใช้งาน และหนึ่งในเหตุผลคือสคริปต์ติดตั้งตรวจสอบการตั้งค่าตัวแปร RPM_ARCH
    • เมื่อเปิดเงื่อนไขด้วยการตั้ง env.RPM_ARCH = true; ก็พบความแตกต่างของ binary liblzma.so
  • เมื่อนำ liblzma.so ทั้งสองไฟล์มาเก็บและเปรียบเทียบ ผลลัพธ์ที่มีแบ็กดอร์มีขนาด 258KB ส่วนผลลัพธ์จากการบิลด์ซอร์ส GitHub หลัง bootstrap มีขนาด 210KB ต่างกันราว 48KB
  • เมื่อเปรียบเทียบ symbol ด้วย nm พบว่ามีการเพิ่ม _cpuid, _get_cpuid, __tls_get_addr@GLIBC_2.3 และ _get_cpuid เป็น symbol ที่มีการบันทึกไว้ในรายงานทางเทคนิคหลายฉบับเกี่ยวกับแบ็กดอร์ xz

แนวทางนำไปใช้และข้อจำกัด

  • กลไกป้องกันที่เสนอคือใช้กับทุกแพ็กเกจที่ถูกบิลด์ในขั้นตอน bootstrap และไม่ได้ใช้ source archive ที่เชื่อถือได้
  • หากเพิ่มแพ็กเกจ *-after-bootstrap เข้าไปใน channel blocker ก็จะทำให้เมื่อบิลด์ล้มเหลวเกิดเป็นสัญญาณเตือนใหญ่ที่ต้องให้ผู้ดูแลเข้ามาแทรกแซง
  • มีการเปิด pull request ใน repository nixpkgs เพื่อเป็น proof of concept สำหรับกรณี xz
  • วิธีนี้ต้องอาศัยสมมติฐานว่าแพ็กเกจเป้าหมาย ทำซ้ำได้ในระดับบิต
    • ใช้ revision 17 รายการของ nixpkgs-unstable ตั้งแต่ปี 2017 ถึง 2023 เป็นตัวอย่าง แล้วบิลด์ non-fixed-output derivation ของ stdenv ใหม่ด้วย nix-build --check
    • ในทุก revision xz ทำซ้ำได้ในระดับบิต
    • ใน 12 จาก 17 revision มีแพ็กเกจที่บิลด์ได้แต่ทำซ้ำไม่ได้ 1–2 แพ็กเกจ เช่น gcc ทำซ้ำไม่ได้อย่างสม่ำเสมอในช่วงปี 2017–2021 และ bash ทำซ้ำไม่ได้จนถึงปี 2019
  • ไม่สามารถใช้วิธีนี้กับแพ็กเกจ stdenv ทั้งหมดได้ แต่ในระยะยาวสามารถเปิดใช้แบบเลือกเฉพาะแพ็กเกจที่มี reproducibility ดี
  • ปัญหา trusting trust ของ Ken Thompson ยังคงเป็นข้อจำกัดเชิงทฤษฎีของวิธีนี้
    • ต้องอาศัยสมมติฐานว่า xz ที่ไม่น่าเชื่อถือในขั้นตอน bootstrap ไม่สามารถปนเปื้อนบิลด์ xz-after-bootstrap ทางอ้อมจนทำให้ผลลัพธ์ดูเหมือนกันได้
    • การโจมตีเช่นนี้อาจซับซ้อนมาก แต่วิธีการนี้ตั้งอยู่บนสมมติฐานดังกล่าว
  • วิธีตรวจจับนี้จะตรวจพบก็ต่อเมื่อการเปลี่ยนแปลงใน tarball ส่งผลต่อผลลัพธ์สุดท้าย
    • เนื่องจากไฟล์ executable ของ NixOS ไม่ได้มีแบ็กดอร์รวมอยู่ หากไม่เปิดเงื่อนไขเพิ่มเติม กรณีนี้ก็คงตรวจไม่พบแบ็กดอร์

1 ความคิดเห็น

 
GN⁺ 2025-03-24
ความคิดเห็นบน Hacker News
  • ต้องชี้ให้เห็นว่า NixOS และ reproducible builds ตรวจไม่พบแบ็กดอร์ xz จริง ๆ แล้ว NixOS เองก็แจกจ่ายบิลด์ xz ที่เป็นอันตรายให้ผู้ใช้ด้วย เพียงแต่มัลแวร์ไม่ได้เล็งเป้า NixOS จึงไม่ทำงานเท่านั้น
    นักพัฒนา NixOS ก็เคยบอกว่า “ตอนที่แบ็กดอร์ถูกเปิดเผย ผม/ฉันตกใจที่พบว่า xz เวอร์ชันอันตรายถูกแจกจ่ายไปยังผู้ใช้ของเราแล้ว” เช่นเคย ทฤษฎีกับความจริงไม่เหมือนกัน และสิ่งที่ทำให้ xz เกิดขึ้นได้ไม่ใช่ช่องโหว่ทางเทคนิคเท่าไร แต่เป็น ช่องโหว่ของมนุษย์ในโลกจริง ชุมชนมักไม่ค่อยยอมรับว่าปัญหาแบบนี้ไม่อาจแพตช์ได้ด้วยซอฟต์แวร์ที่ดีกว่าเสมอไป

    • การตั้งค่าเชิงประกาศของ Nix ค่อนข้างมีประโยชน์ในการเพิ่มความสามารถในการป้องกันการโจมตีได้หลายทาง แต่ยังมีศักยภาพอีกมากที่ยังไม่ได้ใช้ ส่วนตัวแล้วอยากให้ลงมือทำ คอนเทนเนอร์ใช้ครั้งเดียวแบบละเอียด เป็นอันดับแรก และ Guix ก็มีฟีเจอร์แบบนี้อยู่แล้ว
      ถ้าสามารถรันทุกโปรเซสด้วยสิทธิ์จำกัด และทำให้มันเข้าถึงแม้แต่ ~/ ไม่ได้ ยกเว้นไดเรกทอรีที่จำเป็นต่อการทำงาน ก็จะป้องกันกรณีเช่นแพ็กเกจ pip ที่เป็นอันตรายขโมยคีย์ SSH ได้ อย่างไรก็ตาม ผม/ฉันคิดว่าเหตุผลที่แบ็กดอร์ xz ไม่ทำงานบน NixOS เป็นเพราะ โครงสร้างไฟล์ซิสเต็มแบบไม่ใช่ FHS ที่แปลกเฉพาะของ NixOS
    • ถึงอย่างนั้นบทความนี้ก็ดี NixOS เสนอแนวทางเชิงเทคนิคเพื่อป้องกันอาร์ติแฟกต์จากการบิลด์ที่แยกจากซอร์สโค้ด หรือก็คืออาร์ติแฟกต์ที่ทำซ้ำไม่ได้ และ แบ็กดอร์ xz ก็ซ่อนอยู่ในอาร์ติแฟกต์จากการบิลด์พอดี
    • ใช่ ชื่อเรื่องดูเหมือนจะสื่อว่าวิธีของ Nix อาจตรวจพบแบ็กดอร์ได้ แต่ในความเป็นจริงบทความใกล้เคียงกับการเสนอว่า ควรเปลี่ยน Nix อย่างไร จึงจะตรวจพบแบ็กดอร์แบบนั้นได้
    • ดีที่เน้นข้อเท็จจริงว่า reproducible builds ไม่ได้จับแบ็กดอร์ xz ได้จริงก่อนเส้นทางการค้นพบอื่น ๆ
      ทุกวันนี้ ความจริงในทางปฏิบัติมักถูกด้อยค่า หากมันไม่ตรงกับความรู้สึกหรือค่านิยมส่วนตัวเกี่ยวกับความจริงเชิงวัตถุ ผม/ฉันก็มีค่านิยมส่วนตัว แต่ไม่ได้มองว่าความจริงในทางปฏิบัติสำคัญน้อยกว่าความรู้สึกของผม/ฉันต่อมัน เหมือนคำพูดที่ชอบพูดกันว่า ความต่างระหว่างทฤษฎีกับความจริงคือ ตามทฤษฎีแล้วทั้งสองอย่างเหมือนกัน แต่ในความเป็นจริงไม่ใช่ หวังว่าการตระหนักว่า reproducible builds ของ NixOS อาจจับการโจมตี xz ได้แต่กลับไม่ได้นั้น จะนำไปสู่การพัฒนาให้วิเคราะห์บิลด์แบบนั้นและค้นหาการโจมตีอื่น ๆ ได้เร็วขึ้นในอนาคต
    • เหตุผลออกจะตลกอยู่ บูตสแตรปของ NixOS ดาวน์โหลดซอร์สโค้ดมา และซอร์สนั้นเป็น tarball ที่ถูกบีบอัดด้วย xz
  • รู้สึกว่าผู้เขียนมองแคบเกินไปกับวิธีที่เกิดขึ้นโดยบังเอิญในครั้งนี้ กรณี Jia Tan มีตัวอย่างแค่หนึ่งเดียว ดังนั้นการคิดว่ามีเพียงวิธีนั้นเท่านั้นที่เป็นไปได้จึงสายตาสั้น
    เราสามารถจินตนาการได้หลายสถานการณ์ที่แนวป้องกันที่เสนอไว้ตรงนี้ใช้ไม่ได้ แม้ในฐานะผู้ใช้ Nix ผม/ฉันก็คิดว่าโอกาสที่ NixOS จะจับเรื่องนี้ได้มีน้อย เพราะในความเป็นจริงมันก็จับไม่ได้ แม้เพิ่งบอกไปว่าครั้งหน้าอาจเกิดขึ้นต่างออกไป แต่การเชื่อใจ Nix โดยไม่มีหลักฐานก็โง่เขลาเช่นกัน

  • ในเรื่องนี้ NixOS ไม่ค่อยเกี่ยวเท่าไร เพราะแบ็กดอร์ xz เล็งเป้าไปที่ Red Hat และ Debian โดยเฉพาะ
    ถ้าใช้ตรรกะเดียวกัน การบอกว่าแบ็กดอร์ xz ไม่กระทบ Windows ก็เกี่ยวข้องในระดับใกล้เคียงกัน น่าขันที่ท้ายที่สุดแบ็กดอร์นี้ถูกค้นพบโดยพนักงาน Microsoft ซึ่งเป็นจุดที่มักถูกมองข้าม

    • ถ้าเป็น NixOS หรือ Guix ที่ปรับปรุงขึ้นอีกเล็กน้อย ก็น่าจะจับแบ็กดอร์นี้ได้โดยอัตโนมัติทันทีที่มันเข้ามาใน repository ดังนั้นจึงเกี่ยวข้อง
  • บทความบอกว่าดิสโทรควรดึงซอร์สโค้ดโดยตรงจาก ระบบควบคุมเวอร์ชัน เช่น Github แทน tarball สำหรับติดตั้งแบบดั้งเดิม
    แต่ไม่ค่อยเข้าใจว่าสิ่งนี้แก้ปัญหาอะไร ผู้ดูแลที่ประสงค์ร้ายก็แค่เพิ่มก้อนข้อมูลไบนารีเข้าไปใน repository ซอร์สโค้ดโดยตรงไม่ได้หรือ? ผู้เขียนดูจะมองว่า Github น่าเชื่อถือราวกับตรวจสอบโค้ดให้ แต่แน่นอนว่า Github ไม่ได้ทำการตรวจสอบแบบนั้น

    • สิ่งที่วิธีนี้แก้คือปัญหาที่ “สิ่งที่ถูกตรวจทาน” กับ “ซอร์สโค้ดที่ใช้บิลด์ซอฟต์แวร์” มักเป็นคนละอย่างกัน
      reproducible builds ที่ผ่านการตรวจยืนยันแล้วอาจช่วยป้องกันกรณีอย่างการบุกรุก xz utils หรือการดัดแปลง SolarWinds Orion ได้ และคุ้มค่าพอที่จะทำ
    • คำวิจารณ์นั้นไม่ค่อยตรงประเด็น ถ้าบิลด์จากซอร์ส คุณและทุกคนสามารถตรวจซอร์สได้ แต่ถ้าบิลด์จาก tarball ที่ถูกจัดเตรียมไว้ กระบวนการ autoconf จะเปลี่ยนไฟล์ ทำให้โดยเนื้อแท้แล้วมันต่างจากซอร์สดั้งเดิม
      ถ้าดาวน์โหลดไบนารีจาก Github release มารัน ก็ไม่มีทางอื่นนอกจากต้องเชื่อใจผู้ดูแลอย่างสมบูรณ์ Nix ทำแบบนั้นเฉพาะกับแพ็กเกจปิดซอร์สเท่านั้น
  • ประเด็นหลักพึ่งพาข้อเท็จจริงที่ว่าผู้ดูแล XZ ซ่อนโค้ดอันตรายไว้ใน tarball ที่ไม่ได้ check-in เข้า Git
    ผู้เขียนแสดงให้เห็นว่า Nix สามารถตั้งค่าให้สร้าง tarball จาก Git แล้วนำไปใช้ในการบิลด์ไบนารีได้ แต่ไม่เห็นว่าทำไมฟีเจอร์นี้จึงจำเป็นต้องเป็นของ Nix หรือ NixOS ระบบบิลด์ใด ๆ รวมถึงสิ่งที่เข้าไปอยู่ใน RPM หรือ Deb ก็สามารถตั้งค่าให้สร้าง tarball เป็นขั้นกลางได้ทั้งนั้น อันที่จริง Debian ทำงานโดยมี reproducible builds เป็นเป้าหมายสำคัญมานานแล้ว https://wiki.debian.org/ReproducibleBuilds

    • จริง ๆ แล้วบทความอ้างถึงโปรเจกต์ reproducible-builds ในส่วน “Leveraging bitwise reproducibility” ประเด็นของบทความนี้มีสองข้อ
      ข้อแรก กระบวนการบิลด์ของ NixOS ต้องใช้ xz เร็วเกินไปในช่วงต้นของการบูตสแตรป จึงไม่สามารถทำ การบิลด์จากซอร์สทั้งหมด ของ xz ได้ ข้อที่สอง เสนอการปรับ nixpkgs เพื่อให้ตรวจจับโดยอัตโนมัติว่า dependency ของ nixpkgs ที่จำเป็นในช่วงต้นของการบูตสแตรปถูกบุกรุกหรือไม่ แน่นอนว่า ecosystem อื่น ๆ ก็สามารถพยายามบิลด์จากซอร์สทั้งหมดเพื่อหาความไม่ตรงกันได้เช่นกัน แก่นของบทความคือปัจจุบัน nixpkgs ยังทำสิ่งนั้นไม่ได้
  • ถ้าจะโฟกัสกรณีที่ NixOS น่าจะป้องกันได้ ควรดู เหตุการณ์ CrowdStrike แค่ความสามารถในการบูตกลับไปใช้การตั้งค่าของเมื่อวานได้ หากการตั้งค่าของวันนี้ใช้ไม่ได้ ก็น่าจะช่วยบรรเทาความเสียหายส่วนใหญ่ได้แล้ว

    • แต่เรื่องนั้นเป็นปัญหาของ Windows ที่ไม่มีความยืดหยุ่นในการบูตมากกว่า Ubuntu ก็ทำแบบนั้นได้บน ZFS
  • หากใช้เฟรมเวิร์กที่เชื่อถือ ก็จะปลอดภัยจนกว่าเฟรมเวิร์กนั้นจะถูกโจมตี แบ็กดอร์ xz อาจถูกค้นพบแล้วก็ได้ แต่ไม่ได้ถูกออกแบบมาเพื่อให้ทำงานในระบบนิเวศของ Nix
    สักวันหนึ่งหากนักพัฒนาหลักของ Nix เป็นสายลับ หรือเกิดสถานการณ์ทำนองเดียวกัน การโจมตีที่เล็งเป้าระบบนิเวศของ Nix ก็จะเกิดขึ้นด้วย ไม่อยากให้ตอบทำนองว่า Nix ปลอดภัยโดยเนื้อแท้ ถึงขั้นว่าถ้า Nix ถูกโจมตีสำเร็จภายใน 1–2 ปีข้างหน้า ก็อยากจะกลับมาหาแล้วให้ยอมรับว่าคิดผิด

    • เกณฑ์ชี้วัดทั้งในอดีตและอนาคต ไม่ใช่ความปลอดภัยแบบสัมบูรณ์ นั่นเป็นเกณฑ์ที่เป็นไปไม่ได้ซึ่งไม่มีอะไรทำได้ถึง อย่างไรก็ดี เป็นข้อเท็จจริงเชิงวัตถุว่าซอฟต์แวร์ในปัจจุบันโดยทั่วไปปลอดภัยกว่าเมื่อ 30 ปีก่อน
      ข้ออ้างที่หนักแน่นกว่าคือ “Nix โจมตียากกว่าและมีต้นทุนสูงกว่าระบบบิลด์แบบดั้งเดิม” ดังนั้นถ้าพบวิธีโจมตี Nix แบบต้นทุนต่ำได้ ค่อยกลับมาได้ ก่อนถึงตอนนั้น ในระดับเทคนิค การพูดว่า Nix โจมตียากกว่าระบบทางเลือกอย่างน้อยก็ฟังขึ้น และในทางปฏิบัติก็มีความเป็นไปได้สูงมาก
    • แม้แบ็กดอร์ไม่ได้เล็งเป้า Nix แต่หากไม่อยากถูกเปิดโปง มันก็ต้องไม่ทำให้เกิดความสงสัยแม้ในระหว่างที่ถูกบิลด์บน Nix
  • NixOS อาจก้าวหน้ากว่านิดหน่อย แต่ดิสทริบิวชันอื่นส่วนใหญ่ก็คอมไพล์ทุกอย่างจากซอร์ส ตรวจสอบด้วยวิทยาการเข้ารหัสว่าซอร์สที่ใช้นั้นไม่ถูกแก้ไข และมี การพึ่งพาที่ระบุเวอร์ชัน ระหว่างแพ็กเกจ Debian ก็มีบิลด์ที่ทำซ้ำได้เช่นกัน
    ปัญหาอยู่ที่ระบบบิลด์ไม่ได้ลบไฟล์อ็อบเจกต์ที่คอมไพล์ไว้ล่วงหน้าก่อนจะบิลด์จากซอร์ส ต่อให้แก้จุดนั้นแล้ว หากไม่มีใครตรวจสอบซอร์สโค้ด ก็ยังสามารถเพิ่มแบ็กดอร์ได้มากเท่าที่ต้องการ และไม่ว่า NixOS หรือดิสทริบิวชันอื่นก็ไม่สามารถป้องกันเรื่องนี้ได้

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

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