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

อย่างไรก็ตาม มันไม่ได้ทำงานตามที่คาดไว้เสมอไป เนื่องจากการพึ่งพาบางอย่างเป็นการพึ่งพาแบบเปลี่ยนผ่าน การอัพเกรดมันอาจเป็นงานที่ยากลำบากสำหรับเครื่องมือเหล่านี้ เพราะพวกมันไม่รู้ผลกระทบของการเปลี่ยนแปลงและตัดสินใจอย่างไรเมื่อมีข้อขัดแย้ง เราจำเป็นต้องจัดการกับกรณีเหล่านี้ด้วยตนเอง
วิธีการที่ไม่ทำงาน#
- คำสั่งอย่างเป็นทางการเช่น
pnpm up จะทำให้ไฟล์ pnpm-lock.yaml ของคุณยุ่งเหยิง มี ปัญหา เกี่ยวกับเรื่องนี้ซึ่งยังคงเปิดอยู่ในขณะที่เขียน
- การติดตั้งเวอร์ชันล่าสุดของการพึ่งพาโดยตรงที่มีการพึ่งพาแบบเปลี่ยนผ่านเป้าหมายอาจไม่สามารถทำงานได้ หากการพึ่งพาโดยตรงไม่ได้อัพเกรดการกำหนดเวอร์ชัน การพึ่งพาแบบเปลี่ยนผ่านจะไม่ได้รับการอัพเกรด เนื่องจากมันได้ถูกแก้ไขและล็อกในไฟล์
pnpm-lock.yaml
ทางออก#
ฟิลด์ overrides เป็นฟีเจอร์ที่ทรงพลังใน PNPM ที่ช่วยให้คุณสามารถแทนที่การแก้ปัญหาเวอร์ชันได้บางส่วน เราจะใช้ฟีเจอร์นี้เพื่ออัพเกรดการพึ่งพาแบบเปลี่ยนผ่านและทำให้การเปลี่ยนแปลงน้อยที่สุด
ให้ใช้การแจ้งเตือน Dependabot ข้างต้นเป็นตัวอย่าง มันบอกเราว่าแพ็กเกจ follow-redirects มีช่องโหว่ด้านความปลอดภัย และเวอร์ชันที่ได้รับการแก้ไขคือ 1.15.6 อย่างไรก็ตาม การพึ่งพาโดยตรง gatsby ใช้ axios ซึ่งพึ่งพา [email protected]
ขั้นตอนที่ 1: ค้นหาการพึ่งพาแบบเปลี่ยนผ่าน#
มีหลายวิธีในการค้นหาการพึ่งพาแบบเปลี่ยนผ่าน แต่ขอแนะนำวิธีที่ตรงไปตรงมาที่สุด: ค้นหาไฟล์ pnpm-lock.yaml
แล้ว "pnpm why" ล่ะ?
คำสั่ง pnpm why <package> มีประโยชน์จริงๆ อย่างไรก็ตาม มันอาจทำให้คุณสับสนในกรณีนี้ ตัวอย่างเช่น เมื่อฉันรัน pnpm why follow-redirects นี่คือส่วนหนึ่งของผลลัพธ์:
จริงๆ แล้ว มีเพียงการแก้ไขเดียวสำหรับ follow-redirects ในไฟล์ pnpm-lock.yaml คำสั่ง pnpm why อาจแสดงให้คุณเห็นหลายเส้นทางที่ขึ้นอยู่กับเวอร์ชันเดียวกันของแพ็คเกจนี้
ขั้นตอนที่ 2: เพิ่มการแทนที่#
กรณีที่ง่ายที่สุดคือมีการแก้ไขเดียวในไฟล์ pnpm-lock.yaml คุณสามารถเพิ่มการแทนที่ไปที่ไฟล์ package.json ได้โดยตรง:
ถ้าคุณอยู่ในสภาพแวดล้อมการทำงานหลายโปรเจกต์ คุณควรเพิ่มการแทนที่ไปที่ไฟล์ package.json ของรากสภาพแวดล้อมการทำงานหลายโปรเจกต์
ขั้นตอนที่ 3: ใช้การเปลี่ยนแปลง#
รัน pnpm install เพื่อใช้การเปลี่ยนแปลง เราสามารถเห็นว่าแพ็กเกจ follow-redirects ถูกอัพเกรดเป็น 1.15.6 ในไฟล์ pnpm-lock.yaml ด้วยการเปลี่ยนแปลงที่น้อยที่สุด
ตอนนี้คุณสามารถลบฟิลด์ overrides ออกจากไฟล์ package.json เพื่อให้มันสะอาด จากนั้นรัน pnpm install อีกครั้งเพื่อยืนยันว่าการเปลี่ยนแปลงสามารถใช้ได้โดยไม่มีฟิลด์ overrides
การแก้ไขปัญหา#
ขั้นตอนข้างต้นเป็นกรณีที่เหมาะสม สิ่งต่างๆ อาจไม่เป็นไปตามที่คาดไว้เสมอไป นี่คือเคล็ดลับบางประการในการแก้ไขปัญหา:
เวอร์ชันถูกกลับคืนหลังจากลบฟิลด์ "overrides"#
สิ่งนี้อาจเกิดขึ้นเมื่อแพ็คเกจที่พึ่งพามีเวอร์ชันคงที่หรือช่วงที่ไม่รวมถึงเวอร์ชันเป้าหมาย ตรวจสอบไฟล์ package.json ของแพ็คเกจที่พึ่งพา ในกรณีนี้คือ axios เพื่อดูว่ามีการใช้หรือไม่
หากเป็นเช่นนั้น คุณต้องเก็บฟิลด์ overrides ไว้ในไฟล์ package.json จนกว่าแพ็คเกจที่พึ่งพาจะอัพเกรดการกำหนดเวอร์ชัน
มีการแก้ไขหลายรายการสำหรับการพึ่งพาแบบเปลี่ยนผ่าน#
เมื่อโปรเจกต์เติบโตขึ้น ไฟล์ pnpm-lock.yaml อาจมีการแก้ไขหลายรายการสำหรับแพ็คเกจเดียวกัน ตัวอย่างเช่น อาจมีสองเวอร์ชันหลักของแพ็คเกจเดียวกัน foo:
รายงานช่องโหว่แสดงว่า [email protected] มีปัญหาด้านความปลอดภัยซึ่งได้รับการแก้ไขใน 1.0.1 และ [email protected] ไม่ได้รับผลกระทบ เราไม่สามารถเพิ่มการแทนที่ให้กับ foo ได้อย่างง่าย ๆ:
- ถ้าเราเพิ่มการแทนที่
"foo": "^1.0.1" [email protected] จะถูกลดระดับเป็น 1.0.1 ซึ่งอาจทำให้โปรเจกต์เสียหาย เพราะ [email protected] อาจมีฟีเจอร์บางอย่างที่ถูกใช้ในแพ็คเกจที่พึ่งพา
- ถ้าเราเพิ่มการแทนที่
"foo": "^2.0.0" [email protected] จะถูกอัพเกรดเป็น 2.0.0 ซึ่งอาจทำให้โปรเจกต์เสียหาย เพราะ [email protected] อาจมีการเปลี่ยนแปลงที่ทำลายการทำงานบางอย่าง
สมมติว่า foo ทำตาม Semantic Versioning เราสามารถเพิ่มการแทนที่แบบนี้:
วิธีนี้จะอัพเกรด [email protected] เป็น 1.0.1 และเก็บ [email protected] ไว้เหมือนเดิม
สรุป#
ก่อนที่ PNPM จะรองรับการอัพเกรดการพึ่งพาแบบเปลี่ยนผ่านโดยตรง ฟิลด์ overrides เป็นทางออกที่ดีในการแก้ไขช่องโหว่ด้านความปลอดภัยโดยไม่ทำลายสิ่งต่างๆ ฉันหวังว่าบทความนี้จะช่วยให้คุณจัดการกรณีเหล่านี้ได้อย่างมีประสิทธิภาพมากขึ้น ใน Logto เราใช้วิธีนี้เพื่อให้การพึ่งพาของเราทันสมัยและปลอดภัย