11 คะแนน โดย GN⁺ 2025-09-20 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • การโจมตีซัพพลายเชนคือรูปแบบที่มี การอัปเดตที่เป็นอันตราย แอบแฝงเข้ามาในโค้ดโอเพนซอร์ส และ Obsidian ใช้ กลยุทธ์ลดการพึ่งพาภายนอกตั้งแต่ต้น เพื่อลดความเสี่ยงนี้
  • ฟีเจอร์ส่วนใหญ่ของแอปถูกพัฒนาขึ้นเองโดยตรง หรือหากจำเป็นก็จะนำ โค้ดที่ fork มา รวมไว้และดูแลภายในโค้ดเบสของตนเอง
  • ไลบรารีขนาดใหญ่ที่จำเป็น (pdf.js, Mermaid, MathJax เป็นต้น) จะถูก ตรึงเวอร์ชัน เพื่อความปลอดภัย และจะอัปเดตอย่างระมัดระวังเฉพาะเมื่อมีแพตช์ด้านความปลอดภัยเท่านั้น
  • dependency ทั้งหมดจะถูก ตรึงไว้ด้วย lockfile และไม่มีการรันสคริปต์ postinstall เพื่อป้องกันการรันโค้ดตามอำเภอใจระหว่างติดตั้ง
  • ด้วย กระบวนการอัปเดตที่รอบคอบและกลยุทธ์หน่วงเวลา นี้ Obsidian จึงสามารถรับมือกับภัยคุกคามที่อาจเกิดขึ้นได้ก่อนที่ชุมชนจะตรวจพบ

การโจมตีซัพพลายเชนคืออะไร

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

กลยุทธ์ลด dependency : Less is Safer

  • Obsidian พึ่งพา ไลบรารีภายนอกจำนวนน้อยมาก เมื่อเทียบกับแอปอื่นในกลุ่มเดียวกัน
  • ฟีเจอร์หลัก (เช่น Bases, Canvas) ถูก พัฒนาขึ้นเองแทนการนำไลบรารีภายนอกมาใช้
    • วิธีนี้ช่วยให้สามารถ ควบคุมโค้ดที่รันอยู่ได้อย่างสมบูรณ์
  • ฟังก์ชันยูทิลิตีขนาดเล็ก แทบทั้งหมด ทีมพัฒนาเขียนขึ้นเอง
  • โมดูลขนาดกลาง หากใบอนุญาตเอื้ออำนวยก็จะ fork แล้วรวมไว้ในโค้ดเบส
  • ไลบรารีขนาดใหญ่ (pdf.js, Mermaid, MathJax เป็นต้น) จะถูก รวมเข้ามาโดยตรึงไว้ที่เวอร์ชันที่ผ่านการตรวจสอบแล้ว และอัปเกรดให้น้อยที่สุด เฉพาะเมื่อพบประเด็นด้านความปลอดภัยที่สำคัญ
  • การเปลี่ยนแปลงจากภายนอกทั้งหมดจะถูกตรวจทานอย่างละเอียดและผ่านขั้นตอนทดสอบอย่างเข้มงวด
  • วิธีนี้ยังช่วย ลดจำนวน sub-dependency ทำให้ลดความเสี่ยงตั้งต้นที่โค้ดอันตรายจะเล็ดลอดเข้ามาได้

องค์ประกอบที่รวมอยู่ในแอปจริง

  • ในแอปที่ผู้ใช้รันจริง จะมีเพียงแพ็กเกจไม่กี่ตัว เช่น Electron, CodeMirror, moment.js เท่านั้นที่ถูกรวมอยู่
  • ส่วนเครื่องมือพัฒนาอื่น ๆ จะใช้เฉพาะในขั้นตอน build ของแอป และ จะไม่ถูกส่งต่อไปยังผู้ใช้ปลายทาง

การตรึงเวอร์ชันและการจัดการ lockfile

  • dependency ภายนอกทั้งหมดจะถูกจัดการผ่าน การตรึงเวอร์ชัน (pin) อย่างเข้มงวด และ การ commit lockfile
  • สิ่งนี้ช่วยให้การติดตั้ง ทำซ้ำได้อย่างสม่ำเสมอ และติดตามการเปลี่ยนแปลงได้ง่าย
  • นโยบาย ไม่รันสคริปต์ postinstall ช่วยปิดกั้นความเป็นไปได้ของการรันโค้ดตามอำเภอใจระหว่างติดตั้งตั้งแต่ต้นทาง

กระบวนการอัปเดตที่ช้าและรอบคอบ

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

"เวลาเผื่อ" เพื่อความเสถียร: Time is a buffer

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

บทสรุป

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

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

 
GN⁺ 2025-09-20
ความคิดเห็นจาก Hacker News
  • หลายความเห็นมองข้ามไปว่าผู้ใช้ส่วนใหญ่ใช้ปลั๊กอินชุมชนของบุคคลที่สามใน Obsidian อยู่จริง ๆ โดยโมเดลความปลอดภัยของปลั๊กอิน Obsidian นั้นอ่อนแอมาก เพราะปลั๊กอินมีสิทธิ์เข้าถึงไฟล์ทั้งหมดใน vault หาก Obsidian พยายามใส่ฟีเจอร์เข้ามาเองให้มากกว่านี้ ความเสี่ยงด้านความปลอดภัยก็คงลดลงได้ หรือจะปรับเป็นโครงสร้างแบบส่วนขยายเบราว์เซอร์ ที่ระบุสิทธิ์ที่ปลั๊กอินใช้และบล็อกการเข้าถึงสิทธิ์ที่ไม่ได้รับอนุญาตก็ได้เช่นกัน ซึ่งทั้งหมดนี้ให้ความปลอดภัยที่ใช้งานได้จริงกับผู้ใช้มากกว่าแนวคิดว่า “พึ่งพาบุคคลที่สามน้อยกว่า” มาก

    • เมื่อก่อนเคยได้ยินคนในวงการซอฟต์แวร์บางคนพูดถึงกรณีที่ไอเดียจากการออกแบบวิดีโอเกมไหลเข้าสู่ซอฟต์แวร์ทั่วไปแบบอื่น ๆ แต่เดี๋ยวนี้แทบไม่ได้ยินแล้ว ถ้าคนแกนหลักจากบริษัทเกมรุ่นเก่าอย่าง Blizzard เขียนหนังสือสรุปอย่างละเอียดว่าระบบปลั๊กอินของ World of Warcraft ในช่วง 10 ปีแรกทำงานอย่างไร มีปัญหาอะไร และเสริมความปลอดภัยกันอย่างไร ก็น่าจะเป็นประโยชน์อย่างมากต่อระบบนิเวศซอฟต์แวร์โดยรวม ระบบปลั๊กอินของหลายโปรเจ็กต์ทุกวันนี้ยังปนเปกันระหว่างความหลวมกับความไม่เป็นมืออาชีพ

    • ปลั๊กอิน Obsidian เข้าถึงได้ไม่ใช่แค่ไฟล์ใน vault แต่รวมถึงไฟล์ทั้งหมดในคอมพิวเตอร์ด้วย เคยชี้ประเด็นนี้ใน Discord มาก่อน แต่ถูกเมิน

    • คิดว่าเหมือน Arch Linux อยู่พอสมควร แม้แต่วิศวกรเองก็ยังจัดการความปลอดภัยได้ยากเวลาต้องดูแลซอฟต์แวร์จาก AUR โดยตรง ดังนั้นการคาดหวังให้ผู้ใช้ทั่วไปเป็นคนรับผิดชอบเรื่องความปลอดภัยเองจึงเกินจริง

    • คิดว่าอีกไม่นานน่าจะมีกรณีข้อมูลรั่วจากปลั๊กอิน Obsidian ออกมาให้เห็น แล้วตอนนั้นทีมถึงจะเริ่มใส่มาตรการป้องกัน อย่างน้อยควรมีระบบ publisher ที่ผ่านการยืนยันตัวตน

    • กำลังพัฒนาปลั๊กอิน Obsidian ในเชิงพาณิชย์อยู่ และอยากให้มีขั้นตอนการตรวจสอบที่เข้มขึ้นสำหรับปลั๊กอินระดับสูงกว่าทั่วไป ถ้ามีทั้งคลังที่ชุมชนช่วยกันดูแลแบบ AUR ของ Arch Linux และอีกคลังที่ตรวจเข้มกว่า ก็น่าจะช่วยทั้งเรื่องความเร็วในการรีวิวปลั๊กอินและความปลอดภัย

  • มีคำอธิบายว่า “การโจมตี supply chain คือการซ่อนอัปเดตอันตรายไว้ในโค้ดโอเพนซอร์สที่หลายแอปใช้ร่วมกัน” แต่ไม่ว่า source code แบบไหนที่ไม่ใช่แค่ FOSS ก็เป็นเป้าการโจมตีได้เหมือนกัน ความคิดที่ว่า FOSS เปราะบางกว่าเสมอเป็นปัญหา

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

    • ทุกวันนี้การสแกนความปลอดภัยมักทำหลังติดตั้ง (post install) การกันไม่ให้มีอะไรถูกรันระหว่างติดตั้งจึงเป็นเรื่องดี และหวังว่าในอนาคตจะมีฟีเจอร์สแกนหรือล็อกข้อจำกัดตั้งแต่ขั้นตอนติดตั้งมากขึ้น ปัจจุบันมีเครื่องมือเชิงพาณิชย์บางตัวทำได้ แต่ยังไม่แพร่หลาย

    • ถึงอย่างนั้นมันก็ยังมีประโยชน์ต่อการปกป้องเครื่อง build เพราะไม่ต้องกังวลว่าสคริปต์สุ่มจาก dependency จำนวนมากจะมาถูกรันบนเครื่องของฉัน

  • นักพัฒนาต้องรับผิดชอบต่อโค้ดทั้งหมดที่แจกจ่ายให้ผู้ใช้ ถ้าไม่ pin dependency ก็แทบไม่ต่างจาก “ดาวน์โหลดโค้ดสุ่มจากอินเทอร์เน็ตแล้วหวังดวง”

    • การ pin dependency อาจทำให้พลาดแพตช์ความปลอดภัยในภายหลัง ซึ่งก็เสี่ยงเช่นกัน ดังนั้นต้องมีระบบที่ทำให้รู้ตัวเมื่อมีแพตช์ความปลอดภัยใหม่ออกมา และต้องเลือกว่าจะ backport แพตช์นั้นหรืออัปเดตไปเวอร์ชันใหม่

    • ต่อให้ pin dependency ไว้ มันก็ยังมี dependency ของมันเองอีกอยู่ดี สุดท้ายก็ยังเป็นโครงสร้างแบบ “ดาวน์โหลดโค้ดสุ่มแล้วหวังเอา” อยู่เสมอ โดยเฉพาะแอปที่ใช้ Electron ซึ่งพ่วงโค้ดมหาศาลมาเลย

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

    • ประเด็นสำคัญคือการเข้าใจว่าทำไมถึงจะใช้แพตช์ และมันเปลี่ยนอะไรบ้าง เราไม่มีเวลาอ่าน source code ทุกบรรทัดกันอยู่แล้ว ก็เลยใช้เครื่องมือและบริการหลัก ๆ อย่าง Npm Audit เพื่อดูข้อมูลสรุปช่องโหว่ ผมใช้กลยุทธ์ชะลอการอัปเดตถ้าไม่จำเป็นจริง ๆ เพราะการอัปเดตเป็นทั้ง attack vector และเป็นสาเหตุหลักของบั๊กด้วย แต่ก็ต้องตรวจเป็นประจำว่าเราเปิดรับช่องโหว่อะไรอยู่บ้าง ถ้าเป็นช่องโหว่ในฟีเจอร์ที่ไม่ได้ใช้ บางครั้งก็เลื่อนการอัปเดตออกไป และจะรีบอัปเดตก็ต่อเมื่อเป็นปัญหาร้ายแรงจริง ๆ ความปลอดภัยเป็นกระบวนการเชิงรุกและต่อเนื่อง และการตอบสนองก็ควรขึ้นกับระดับความเสี่ยงที่องค์กรยอมรับได้ ไม่ใช่แค่ “อัปเดตเสมอ” หรือ “ไม่อัปเดตเด็ดขาด”

    • ช่วงนี้ทุกครั้งที่อัปเดต Z-WaveJS UI ก็มักมีการอัปเดต dependency ตามมาเรื่อย ๆ ด้วยรูปแบบที่ไม่น่าพอใจแบบนี้เลยต้องคอยตรวจเอง ทุกวันนี้เป็นยุคที่ทุกคนพึ่งพา dependency ของ dependency กันหมดแล้ว “ไม่มีวันจบ” แค่อัปเดตอัตโนมัติครั้งเดียวก็เสี่ยงได้

    • เวลาอัปเดตย่อมมีโอกาสทั้งดีขึ้นหรือแย่ลงเสมอ และใน ecosystem ของ npm (ซึ่ง Obsidian ก็อยู่ในนั้น) ความเสี่ยงยิ่งสูงกว่า npm ต้องอาศัยคนเข้ามาจัดการถอดแพ็กเกจอันตราย ทำให้การจัดการช้า การจงใจหน่วงการอัปเดตไว้บ้างจึงพอช่วยป้องกันได้

    • ช่วงหลังมานี้มีแนวโน้มที่จะรอสักหน่อยหลัง patch release ออก แล้วค่อยติดตั้ง เพราะปัจจุบันอุบัติเหตุมักถูกตรวจพบภายในไม่กี่ชั่วโมง หลายบริษัทก็คอยเฝ้าระวัง npm และทำธุรกิจด้านความปลอดภัยด้วย pnpm สามารถตั้งค่าให้ติดตั้งเฉพาะแพ็กเกจที่เผยแพร่มาแล้วเกิน X นาทีได้ ฉันมักรออย่างน้อย 24 ชั่วโมง การตั้งค่า minimumreleaseage ของ pnpm

    • การโจมตีที่แพ็กเกจของฉันเจอเมื่อ 2 สัปดาห์ก่อน เล็งไปที่ patch release ไม่ใช่สคริปต์ postinstall และเพราะระบบสแกนอัตโนมัติจับได้เร็ว ประเด็นนี้เลยไม่ได้ถูกพูดถึงมากเหมือนก่อน หากพบช่องโหว่ในแพ็กเกจ ก็จะมีการแจ้งเตือนทันทีและชัดเจน การใช้ version ranges ถือว่าแย่มากสำหรับการรับมือการโจมตี supply chain

  • ยากจะเห็นด้วยกับคำกล่าวที่ว่าแพ็กเกจไม่ได้ใหญ่ เพราะมีแค่ Electron, CodeMirror และ moment.js เท่านั้น Electron เป็นซอฟต์แวร์ที่ซับซ้อนมากเพราะสร้างบน webview ส่วน moment.js ก็มี API ที่ดีกว่าแทนได้แล้ว ระดับการจัดการ dependency ของ Obsidian จึงดูเป็นเพียงมาตรฐานขั้นต่ำ ไม่ได้รู้สึกว่าเป็นนโยบายความปลอดภัยที่โดดเด่นอะไรนัก ถึงอย่างนั้นการตรวจ security audit เป็นประจำก็ถือเป็นเรื่องดี

  • ปกติผมใช้แอปอื่นที่ไม่ใช่ Obsidian แต่มาเริ่มสนใจ Obsidian ขึ้นเรื่อย ๆ การที่มันเป็นแอป Electron ทำให้กินทรัพยากรเยอะและไม่ใช่ native เลยทำให้รู้สึกไม่ค่อยไว้ใจ JS อยู่เสมอ สงสัยว่าผมอาจจะหัวเก่าเกินไปหรือเปล่า

    • JavaScript เป็นภาษาที่ปลอดภัยมาก เว็บเบราว์เซอร์คือกรณีตัวอย่างที่ประสบความสำเร็จในการรัน JavaScript อย่างปลอดภัยในระดับโลก แต่ละเว็บไซต์ไม่สามารถอ่านข้อมูลของกันและกันได้ Electron เองก็ sandbox JavaScript ด้วยเอนจิน v8 ถ้าเลี่ยงการรันโค้ดจากอินพุตของผู้ใช้ ก็ถือว่าปลอดภัยมาก ปัญหาการโจมตี supply chain เป็นเรื่องของ npm เอง ไม่ใช่ปัญหาของภาษา JS และ npm มีหน้าที่ต้องใช้มาตรการความปลอดภัยที่เข้มงวดกว่านี้ตอนเผยแพร่แพ็กเกจ

    • ไม่ว่าจะวัดด้วยเกณฑ์ไหน JavaScript ก็เป็นหนึ่งในภาษาที่มีการใช้งานมากที่สุดในโลก รันได้แทบทุกคอมพิวเตอร์และสมาร์ตโฟน ยิ่งใช้เยอะก็ยิ่งพบประเด็นความปลอดภัยบ่อยขึ้น ไม่มีหลักฐานว่าแอป native จะปลอดภัยกว่าเสมอไป

    • แอป Electron ไม่ได้เป็นปัญหาอะไร GitHub, VS Code, Slack, Discord, Postman ล้วนสร้างบน Electron ทั้งนั้น ผมชอบถามเหมือนกันว่า ในแอปจดโน้ต Markdown มันจะมีงานอะไรที่ทำให้ประสิทธิภาพเป็นปัญหาจริง ๆ หรือคุณยังใช้โน้ตบุ๊กเก่ามาก ๆ เปิดผ่านเบราว์เซอร์ Lynx แบบข้อความล้วนอยู่กันแน่

    • ผมไม่ค่อยชอบ Electron เท่าไร (เลยชอบ tauri มากกว่า) แต่ตัว Obsidian เองยอดเยี่ยมมาก จึงไม่จำเป็นต้องเมินมันเพียงเพราะใช้ Electron แถมยังเอาไปเชื่อมกับ MCP เพื่อใช้เป็นคลังความรู้ส่วนตัวได้ดีด้วย แนะนำเลย

    • Electron หนักจริง บน PC อาจไม่ค่อยมีปัญหา แต่บนมือถือถ้ามีโน้ตเป็นพัน ๆ ไฟล์ แอปจะเปิดช้าแม้ไม่ใช้ปลั๊กอิน ผู้ใช้หลายคนเลยอ้อมไปใช้ปลั๊กอินหรือแอปสำหรับจดเร็วแทน แต่ก็ยังอยากเห็น Obsidian แบบ native ที่เบากว่านี้

  • Obsidian สร้างบน Electron และด้วยธรรมชาติของมันก็ย่อมมีทั้งความหนักและความเสี่ยงด้านความปลอดภัย

    • แต่ก็รองรับ UX ที่เหมือนกันทุกแพลตฟอร์ม และให้การเข้าถึงได้ใกล้เคียง native
  • ใช้ Emacs กับ Org-Roam และรันใน VM ที่ไม่มีการเชื่อมต่อเครือข่าย (Qube ของ Qubes OS) ถึงอย่างนั้นก็ยังไม่สามารถตรวจโค้ดทั้งหมดที่รันอยู่ใน Emacs ได้ด้วยตัวเอง

  • ถ้าอยากได้แอป native และลดความเสี่ยงด้าน supply chain ให้ต่ำลงอีก ทางเลือกหนึ่งคือ Zim wiki ที่ใช้ GTK และมีแพ็กเกจในลินุกซ์ดิสโทรหลัก ๆ ไปที่ Zim wiki

    • แต่ Zim wiki ไม่มีแอปมือถือแบบ native และไม่มีฟังก์ชันซิงก์ จุดนี้เองที่ทำให้ยังเอนเอียงมาทาง Obsidian ถ้าแค่ไม่ติดตั้งปลั๊กอินสุ่ม ๆ ก็น่าจะปลอดภัยพอสมควร