วิกฤต NPM ด้านความปลอดภัย: นักพัฒนาเรียกร้องการป้องกันที่ดีกว่าต่อการโจมตี Supply Chain

ทีมชุมชน BigGo
วิกฤต NPM ด้านความปลอดภัย: นักพัฒนาเรียกร้องการป้องกันที่ดีกว่าต่อการโจมตี Supply Chain

ชุมชนนักพัฒนา JavaScript กำลังเผชิญกับความกังวลด้านความปลอดภัยที่เพิ่มขึ้น เนื่องจากการโจมตี NPM supply chain มีความซับซ้อนและความถี่ที่เพิ่มมากขึ้น เหตุการณ์ที่เกิดขึ้นเมื่อเร็วๆ นี้ได้เปิดเผยช่องโหว่สำคัญในวิธีที่นักพัฒนาจัดการ dependencies ทำให้เกิดการถกเถียงอย่างรุนแรงเกี่ยวกับการเปลี่ยนแปลงพื้นฐานที่จำเป็นเพื่อปกป้องโปรเจกต์ซอฟต์แวร์

การแสดงภาพความสำคัญของแนวทางปฏิบัติด้านความปลอดภัย npm ในชุมชนนักพัฒนา
การแสดงภาพความสำคัญของแนวทางปฏิบัติด้านความปลอดภัย npm ในชุมชนนักพัฒนา

Lockfiles ไม่เพียงพอ: ความขัดแย้งเรื่อง Version Pinning

การถกเถียงอย่างรุนแรงได้เกิดขึ้นเกี่ยวกับว่านักพัฒนาควรกำหนด version ที่แน่นอนของ dependencies ทั้งหมดหรือไม่ โดยไปไกลกว่าการป้องกันด้วย lockfile แบบดั้งเดิม แม้ว่า lockfiles จะถูกออกแบบมาเพื่อให้แน่ใจว่าการ build จะทำซ้ำได้ แต่สมาชิกในชุมชนโต้แย้งว่ามันไม่สามารถป้องกันโค้ดที่เป็นอันตรายจากการทำงานระหว่างการติดตั้ง ความขัดแย้งนี้มีจุดศูนย์กลางอยู่ที่พฤติกรรมที่สับสนของ NPM ที่คำสั่งต่างๆ จัดการ lockfiles แตกต่างกัน ทำให้เกิดช่องโหว่ด้านความปลอดภัยที่ไม่คาดคิด

การอภิปรายนี้เผยให้เห็นความผิดหวังอย่างลึกซึ้งต่อการตัดสินใจในการออกแบบของ NPM นักพัฒนาบางคนรายงานว่า npm install มาตรฐานยังคงสามารถอัปเดต dependencies ได้แม้จะมี lockfiles ในขณะที่ npm ci ให้พฤติกรรมที่คงที่ตามที่คาดหวัง ความไม่สอดคล้องกันนี้ได้สร้างช่องว่างด้านความไว้วางใจที่ผู้โจมตีสามารถใช้ประโยชน์ได้

คำสั่ง NPM ด้านความปลอดภัยที่สำคัญ

  • npm ci --frozen-lockfile - ติดตั้งเวอร์ชันที่แน่นอนจาก lockfile
  • npm config set ignore-scripts true - ปิดใช้งาน lifecycle scripts ทั่วทั้งระบบ
  • npm config set save-exact true - กำหนดเวอร์ชันที่แน่นอนเป็นค่าเริ่มต้น
  • npm audit - สแกนหาช่องโหว่ที่ทราบแล้ว
  • npm pack - ดูตัวอย่างเนื้อหาของแพ็กเกจก่อนเผยแพร่

ปัญหา NPX: การแก้ไข Runtime Dependency

ความกังวลด้านความปลอดภัยที่สำคัญได้เกิดขึ้นรอบๆ NPX ซึ่งเป็นเครื่องมือการทำงานของ package ที่แก้ไข dependencies ในขณะ runtime ในระหว่างเหตุการณ์ colors ปี 2022 ระบบเสียหายทันทีเพราะ NPX ดาวน์โหลดและรันโค้ดแบบ on-demand โดยข้าม safeguards การจัดการ dependency แบบดั้งเดิม พฤติกรรมนี้ทำให้เกือบเป็นไปไม่ได้ที่จะตรวจสอบว่าโค้ดใดจริงๆ ทำงานบนระบบ

นี่หมายความว่าเป็นไปไม่ได้จริงๆ ที่จะให้เหตุผลเกี่ยวกับโค้ดใดที่จะทำงาน และการตรวจสอบทางนิติเวชจะมีปัญหาอย่างมากในการหาว่าคอมพิวเตอร์ได้ทำงานอะไรบ้าง

ฉันทามติของชุมชนชัดเจน: การใช้ NPX ควรหลีกเลี่ยงในสภาพแวดล้อมการผลิตและ CI/CD pipelines ที่พฤติกรรมที่คาดเดาได้เป็นสิ่งสำคัญ

กลยุทธ์การแยก: Docker และสภาพแวดล้อม Air-Gapped

นักพัฒนาหันไปใช้ containerization และสภาพแวดล้อมที่แยกออกมามากขึ้นเพื่อจำกัดพื้นผิวการโจมตี ทีมบางทีมได้ใช้ CI servers แบบ air-gapped ที่ dependencies ถูกคัดสรรด้วยตนเองใน repositories แยกต่างหาก บังคับให้มีการตรวจสอบความปลอดภัยของการเปลี่ยนแปลงทุกครั้ง แม้ว่าวิธีการนี้จะทำให้การพัฒนาช้าลงอย่างมาก แต่ก็พิสูจน์แล้วว่ามีประสิทธิภาพในการป้องกันการประนีประนอม supply chain

สภาพแวดล้อมการพัฒนาแบบ Docker กำลังได้รับความนิยมเป็นโซลูชันระดับกลาง ด้วยการบรรจุโปรเจกต์ Node.js ไว้ในคอนเทนเนอร์ นักพัฒนาสามารถปกป้องเครื่องโฮสต์จาก packages ที่เป็นอันตรายในขณะที่รักษาความเร็วในการพัฒนาผ่าน volume mounting สำหรับ hot reloading

โซลูชันสำหรับ Private Registry

  • GitHub Packages: รวมเข้ากับ repository ของ GitHub
  • Verdaccio: private registry แบบ open source
  • JFrog Artifactory: โซลูชันระดับองค์กร
  • Sonatype Nexus: แพลตฟอร์มสำหรับจัดการ repository
  • Custom proxies: ควบคุมเวอร์ชันของแพ็กเกจและการตรวจสอบความปลอดภัย

วิกฤตการบำรุงรักษา: เหตุใดการโจมตีจึงสำเร็จ

สาเหตุรากของการโจมตี supply chain หลายครั้งสืบย้อนไปถึงความเหนื่อยล้าของผู้ดูแลและธรรมชาติที่ไม่ยั่งยืนของการพัฒนา open source ที่ขับเคลื่อนด้วยอาสาสมัคร Packages ยอดนิยมมักขึ้นอยู่กับอาสาสมัครที่ทำงานหนักเกินไปซึ่งอาจส่งมอบการเข้าถึงให้กับผู้กระทำความผิดที่ปลอมตัวเป็นผู้ร่วมงานที่เป็นประโยชน์ การประนีประนอม good-parts ปี 2019 และ backdoor XZ Linux ปี 2024 แสดงให้เห็นว่าผู้โจมตีที่อดทนสามารถใช้เวลาหลายปีในการสร้างความไว้วางใจก่อนที่จะโจมตี

สมาชิกในชุมชนเน้นย้ำว่าการสนับสนุน open source ทางการเงินผ่านแพลตฟอร์มเช่น GitHub Sponsors และ Open Collective ไม่ใช่แค่เรื่องความยั่งยืน แต่เป็นมาตรการความปลอดภัยที่สำคัญที่ลดความเป็นไปได้ของการประนีประนอมผู้ดูแล

คุณสมบัติด้านความปลอดภัยของตัวจัดการแพ็กเกจทางเลือก

  • Yarn: แฟล็ก --frozen-lockfile, การตั้งค่า enableScripts false
  • PNPM: แฟล็ก --frozen-lockfile, การตั้งค่า enable-scripts false
  • Bun: รองรับ Override fields, การติดตั้งที่เร็วกว่า
  • ทั้งหมดรองรับการ override dependency เพื่อควบคุม transitive dependency

นอกเหนือจากเครื่องมือ: ความจริงของการตรวจสอบโค้ด

แม้จะมีเครื่องมือความปลอดภัยมากมายและโซลูชันการสแกนอัตโนมัติ นักพัฒนาที่มีประสบการณ์เน้นว่าไม่มีอะไรทดแทนการตรวจสอบโค้ดจริงๆ ความท้าทายคือโค้ดใน Git repositories มักแตกต่างจากสิ่งที่แจกจ่ายจริงผ่าน NPM ทำให้การตรวจสอบโค้ดแบบดั้งเดิมไม่เพียงพอ นักพัฒนาต้องตรวจสอบเนื้อหาของไดเรกทอรี node_modules เพื่อเข้าใจว่าอะไรกำลังทำงานจริงในแอปพลิเคชันของพวกเขา

ความจริงนี้ได้นำไปสู่การที่ทีมที่ใส่ใจความปลอดภัยบางทีมลดรอยเท้า dependency อย่างมาก โดยใช้ฟังก์ชันการทำงานที่สำคัญด้วยคุณสมบัติ standard library แทนที่จะใช้ packages ภายนอก แม้ว่าวิธีการนี้จะต้องใช้เวลาในการพัฒนาเริ่มต้นมากกว่า แต่ก็ลดพื้นผิวการโจมตีและภาระการบำรุงรักษาระยะยาวอย่างมาก

อ้างอิง: NPM Security Best Practices