5 คะแนน โดย GN⁺ 2024-09-27 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

กำจัดต้นตอของช่องโหว่ด้านความปลอดภัยของหน่วยความจำ

ผลลัพธ์ที่ดูย้อนแย้ง

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

คำอธิบายทางคณิตศาสตร์

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

กรณีใช้งานจริงใน Android

  • ตั้งแต่ปี 2019 ทีม Android เริ่มเปลี่ยนงานพัฒนาใหม่ไปใช้ภาษาที่ปลอดภัยต่อหน่วยความจำ
  • ณ ปี 2024 ช่องโหว่ด้านความปลอดภัยของหน่วยความจำลดลงจาก 76% เหลือ 24%
  • เมื่อช่องโหว่ด้านความปลอดภัยของหน่วยความจำลดลง ความเสี่ยงด้านความปลอดภัยโดยรวมก็ลดลงด้วย

วิวัฒนาการของกลยุทธ์ด้านความปลอดภัยของหน่วยความจำ

  • รุ่นที่ 1: การแพตช์เชิงรับ - ค้นพบช่องโหว่แล้วจึงแก้ไข
  • รุ่นที่ 2: การบรรเทาเชิงรุก - ทำให้การใช้ประโยชน์จากช่องโหว่ทำได้ยากขึ้น
  • รุ่นที่ 3: การค้นหาช่องโหว่เชิงรุก - ค้นหาช่องโหว่ล่วงหน้า
  • รุ่นที่ 4: การป้องกันที่เชื่อถือได้สูง - เปลี่ยนไปใช้ภาษาที่ปลอดภัยต่อหน่วยความจำเพื่อป้องกันไม่ให้ช่องโหว่เกิดขึ้นตั้งแต่แรก

ข้อดีของการป้องกันที่เชื่อถือได้สูง

  • ตัดวงจรการแข่งขันที่ไม่มีวันจบระหว่างผู้ป้องกันกับผู้โจมตี
  • เพิ่มความปลอดภัยและลดต้นทุนผ่านภาษาที่ปลอดภัยต่อหน่วยความจำ
  • เพิ่มความถูกต้องของโค้ดและประสิทธิภาพการทำงานของนักพัฒนา

จากบทเรียนสู่การลงมือปฏิบัติ

  • ไม่จำเป็นต้องทิ้งหรือเขียนใหม่ทั้งหมดสำหรับโค้ดเดิมที่ไม่ปลอดภัยต่อหน่วยความจำ
  • เร่งการเปลี่ยนผ่านไปสู่ภาษาที่ปลอดภัยต่อหน่วยความจำด้วยการปรับปรุงการทำงานร่วมกัน
  • พัฒนาเครื่องมือเพื่อปรับปรุงการทำงานร่วมกันระหว่าง Rust กับ C++ และ Rust กับ Kotlin

บทบาทของแนวทางรุ่นก่อนหน้า

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

บทสรุป

  • การใช้ภาษาที่ปลอดภัยต่อหน่วยความจำกับโค้ดใหม่ทำให้ช่องโหว่ลดลงแบบเอ็กซ์โปเนนเชียล
  • ผลลัพธ์ที่สม่ำเสมอตลอดกว่า 6 ปีใน Android พิสูจน์ประสิทธิผลของแนวทางนี้

สรุปโดย GN⁺

  • การเปลี่ยนไปใช้ภาษาที่ปลอดภัยต่อหน่วยความจำมีความสำคัญต่อการลดช่องโหว่ด้านความปลอดภัยของหน่วยความจำ
  • กรณีของทีม Android แสดงให้เห็นว่าช่องโหว่ด้านความปลอดภัยของหน่วยความจำลดลงอย่างมาก
  • การปรับปรุงการทำงานร่วมกันเป็นแนวทางที่ใช้งานได้จริงกว่าการเขียนโค้ดเดิมใหม่ทั้งหมด
  • การใช้ภาษาที่ปลอดภัยต่อหน่วยความจำอย่าง Rust สามารถเพิ่มทั้งความปลอดภัยและประสิทธิภาพการทำงานได้พร้อมกัน

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

 
GN⁺ 2024-09-27
ความเห็นจาก Hacker News
  • เป็นบทความที่น่าสนใจ ประเด็นสำคัญคือ เราไม่จำเป็นต้องเขียนทุกอย่างขึ้นมาใหม่ทั้งโลก
    แค่ย้ายงานพัฒนาใหม่ไปใช้ภาษาแบบ memory-safe ก็ช่วยให้ดีขึ้นอย่างมีนัยสำคัญได้แล้ว และง่ายกับถูกกว่าการพอร์ตทั้งหมดมากหากต้องการเห็นผล

    • ผลลัพธ์นี้ชี้ว่าในมุมความปลอดภัย ประโยชน์ของการ เขียนใหม่ทั้งหมด มีอยู่อย่างจำกัด กลยุทธ์ที่คงโค้ด legacy ที่สุกงอมไว้ และใช้ภาษาแบบ memory-safe กับโค้ดใหม่เท่านั้น ให้ความคุ้มค่าต่อค่าใช้จ่ายดีกว่า
      อีกทั้งยังทำให้คุณค่าของภาษาและเครื่องมือที่ผสานรวมกับโค้ด legacy ที่ไม่ปลอดภัยได้อย่างแข็งแรงยิ่งสูงขึ้น
    • การเขียนใหม่มีค่าใช้จ่ายสูงเกินไปจึงเกิดขึ้นได้ยากมาก แต่แนวทางแบบ ค่อยๆ กัดกินจากขอบ กลับมีประสิทธิภาพมาก
      ผมก็สงสัยว่าโค้ดที่เก่ามากๆ จะมีเอฟเฟกต์คล้าย “เส้นโค้งอ่างอาบน้ำ” หรือไม่ ยังจำได้ว่าตอนมีช่องโหว่ร้ายแรงของ OpenSSL น่าจะช่วง Heartbleed หลายคนเห็นโค้ดแล้วถึงกับตกใจ
    • ถ้ามองจากมุมความปลอดภัยผมเห็นด้วย แต่ถ้าจุดประสงค์คืออยากเอา garbage collection ออก หรือลดการใช้ทรัพยากรโดยรวม เรื่องก็อาจต่างออกไป
    • การเขียนโค้ดใหม่ทั้งหมดด้วยภาษาแบบ memory-safe แล้วทำให้ช่องโหว่ด้าน memory safety ลดลงนั้นไม่ใช่เรื่องน่าแปลกใจ เพราะโค้ดใหม่มีโอกาสสร้างปัญหา memory safety แบบใหม่ มากกว่าที่โค้ดเก่าจะถูกพบปัญหาเดิมที่มีอยู่แล้ว
      แต่สิ่งที่น่าประทับใจคือช่วงปี 2019 ถึง 2023 เพียงแค่เพิ่มโค้ดใหม่ด้วยภาษาแบบ memory-safe ซึ่งน่าจะเป็น Rust เป็นส่วนใหญ่และ Kotlin บางส่วน โดยไม่ต้องเขียนใหม่ ก็ทำให้ปัญหาลดลงเกือบ 60% ได้ ผมก็สงสัยว่าทำไมถึงมีช่วงชะงักระหว่างปี 2021 ถึง 2023
      การเอาตัวเลขปี 2024 มาเขียนแบบ extrapolate ดูเหมือนตั้งใจจะทำให้ตัวเลขออกมาสวย และถ้าเปลี่ยนไปวิเคราะห์อธิบายว่าทำไมตัวเลขถึงเพิ่มขึ้นจาก 2022 ไป 2023 น่าจะมีประโยชน์กว่า
      น่าเสียดายที่ไม่มีข้อมูลว่าโค้ด memory-safe ใหม่ถูกเขียนด้วยภาษาอะไรและมากน้อยแค่ไหน ดูเหมือนจะใช้ทั้ง Rust และ Kotlin แต่ก็อยากรู้ว่า Rust คิดเป็น 95% หรือ 50% และถ้าสัดส่วน Kotlin สูง ใช้แทน Rust ในงานด้านไหน
  • กราฟในบทความนี้โดดเด่นมากเรื่อง ความชัดเจนและกระชับ แสดงให้เห็นอย่างดีว่าการเลือกข้อมูลและการติดป้ายกำกับอย่างระมัดระวัง สามารถสอดแทรกแนวคิดที่ต้องการสื่อเข้าไปในเนื้อความได้อย่างเป็นธรรมชาติ
    ข้อสรุปจากข้อเท็จจริงที่ว่าช่องโหว่ลดลงแบบเอ็กซ์โปเนนเชียลคือ ควรโฟกัสกับโค้ดใหม่ล้วนๆ การทุ่มทรัพยากรไปกับโปรเจกต์ “เขียนใหม่เป็น Rust” แบบใหญ่โตและหว่านแห ไม่คุ้มค่าแม้กระทั่งเมื่อเป้าหมายคือ memory safety สูงสุด
    ค่อนข้างลงตัวดีที่กลยุทธ์ที่ง่ายที่สุด และเป็นกลยุทธ์ที่ผู้เชี่ยวชาญ Rust สายปฏิบัติแนะนำ กลับเป็นกลยุทธ์ที่ดีที่สุดในการลดช่องโหว่ด้านหน่วยความจำตามข้อมูลด้วย
    ข้อความที่ว่า “ทีม Android สังเกตว่าอัตราการ rollback ของการเปลี่ยนแปลงที่ทำด้วย Rust ต่ำกว่า C++ ถึงไม่ถึงครึ่ง” น่าประหลาดใจมาก

  • “ช่องโหว่ลดลงแบบเอ็กซ์โปเนนเชียล มันมีครึ่งชีวิต [...] งานวิจัยขนาดใหญ่เรื่องอายุของช่องโหว่ที่นำเสนอใน Usenix Security 2022 ก็ยืนยันปรากฏการณ์นี้เช่นกัน นักวิจัยพบว่าช่องโหว่ส่วนใหญ่อยู่ในโค้ดใหม่หรือโค้ดที่เพิ่งแก้ไขล่าสุด”
    ถ้าอย่างนั้น การ หยุดเพิ่มฟีเจอร์ใหม่ ที่ไม่จำเป็นต่อความปลอดภัย อาจจะดีกว่าก็ได้ Windows LTSC น่าจะเป็น Windows เวอร์ชันที่ปลอดภัยที่สุด

    • สำหรับซอฟต์แวร์ที่มีการดูแลรักษาอยู่ บั๊กแต่ละตัวที่เกิดขึ้นระหว่างการใช้งานปกติย่อมลดลงเมื่อเวลาผ่านไป เพราะเมื่อบั๊กสร้างปัญหา ก็จะมีคนรายงาน และบางส่วนก็ถูกแก้ไข นี่คือกลไกที่ทำให้ลดลง
      แต่ช่องโหว่ที่ยังไม่ถูกนำไปใช้โจมตีนั้นไม่มีกลไกลดลงแบบนี้ มันไม่ก่อให้เกิดคำร้องเรียนจากผู้ใช้หรือรายงานบั๊ก แค่คงอยู่ต่อไป จนกระทั่งฝ่ายตรงข้ามที่มีทรัพยากรและแรงจูงใจมากพอจะค้นพบและนำไปใช้โจมตี
      และตอนนี้ฝ่ายตรงข้ามระดับนั้นมีมากกว่าเมื่อก่อน
    • คำว่า “ช่องโหว่ลดลงแบบเอ็กซ์โปเนนเชียล” น่าจะใช้ได้ไม่ใช่แค่กับช่องโหว่ แต่กับบั๊กทุกชนิดด้วย ในการทดสอบของโปรเจกต์ซอฟต์แวร์เสรี SBCL ที่ผมมีส่วนร่วมก็เห็นปรากฏการณ์นี้ บั๊กใหม่มักเกิดในส่วนที่เพิ่งเปลี่ยนล่าสุด
      แน่นอนว่านี่ไม่ได้แปลว่าบั๊กทั้งหมดอยู่ในโค้ดใหม่เท่านั้น คุณคงเคยเห็นบั๊กที่หลบอยู่มาหลายปีโดยไม่ถูกตรวจพบเหมือนกัน สำหรับบั๊กแบบนั้น ควรถามว่าทำไมการทดสอบถึงพลาดมันไป
      เพราะฉะนั้นการทดสอบควรโฟกัสกับโค้ดที่เพิ่งเปลี่ยน โดยเฉพาะ mutation testing ที่สามารถนำไปใช้เข้มข้นมากกับโค้ดที่เปลี่ยนหรือโค้ดที่ผูกแน่นกับมัน จึงช่วยลดภาระของการทดสอบแบบนี้ได้มาก
      ที่ Google เคยมีระบบที่ใช้ mutation testing แบบนี้ร่วมกับ code review
    • ต่อให้การขายซอฟต์แวร์ไม่จำเป็นต้องมีฟีเจอร์ใหม่เสมอไป แต่ฮาร์ดแวร์ใหม่ อัลกอริทึมความปลอดภัยที่ดีกว่า และการเลิกใช้อัลกอริทึมเดิมอย่างสิ้นเชิง ก็ยังเกิดขึ้นต่อเนื่อง สุดท้ายก็ต้องมีโค้ดใหม่เข้ามาอยู่ดี
    • ยังมีอีกแนวทางหนึ่ง คือคอมไพล์เฉพาะชุดย่อยของฟีเจอร์ที่ต้องการอย่างชัดเจนเท่านั้น
      แน่นอนว่าความเป็นไปได้เชิงปฏิบัติจะแตกต่างกันมากในแต่ละกรณี แต่ก็น่าจะเป็นวิธีที่ควรพบเห็นได้บ่อยกว่าปัจจุบัน
    • เพราะแบบนี้ผมจึงมักแนะนำคนส่วนใหญ่ว่าอย่าเพิ่งใช้ point release ล่าสุดของภาษา หรือไลบรารีในทันที
      เวอร์ชันล้ำหน้าสุด มักมีช่องโหว่ใหม่อยู่มาก โดยทั่วไปแล้วรีลีสที่เก่าสุดซึ่งยังได้รับการสนับสนุนมักปลอดภัยที่สุด
      แน่นอนว่าถ้าฟีเจอร์ของเวอร์ชันใหม่มีคุณค่าเพิ่มก็เป็นข้อยกเว้น แต่โดยรวมแล้วผมคิดว่าควรหลีกเลี่ยงเวอร์ชันที่ลงท้ายด้วย “.0”
  • มีความสัมพันธ์กันระหว่างโค้ดใหม่กับช่องโหว่ด้านหน่วยความจำ บทความบล็อกยังเสนอคำอธิบายที่เป็นไปได้ว่าช่องโหว่มีครึ่งชีวิตที่ลดลงอย่างรวดเร็วด้วย แต่ไม่เข้าใจว่าทำไมถึงระบุว่ามี ความเป็นเหตุเป็นผล ระหว่างสองสิ่งนี้
    ความสัมพันธ์นี้อาจอธิบายได้อย่างสมเหตุสมผลหลายแบบ โค้ดใหม่มักเกี่ยวข้องกับฟีเจอร์ใหม่ และคนก็มักโฟกัสกับการหาช่องโหว่ในฟีเจอร์ใหม่ อีกทั้งโค้ดเก่าอาจผ่านการใช้งานจริงมามากกว่า และอาจได้รันเงื่อนไขขอบเขตที่ซ่อนช่องโหว่ด้านหน่วยความจำอยู่มากกว่า
    รู้สึกไม่สบายใจที่จะบอกว่าโค้ดใหม่ก่อให้เกิดช่องโหว่ด้านหน่วยความจำ และช่องโหว่มีครึ่งชีวิตที่ลดลงอย่างรวดเร็ว ถ้ามองแค่จำนวนอาจจะจริง แต่ถ้านึกถึงช่องโหว่โอเพนซอร์สที่มีผลกระทบสูงอย่าง Heartbleed หรือบั๊ก invalidation ของ CPU cache ก็รู้สึกว่าไม่จริงในแง่ผลกระทบ

    • ดูเหมือนว่าจะมองได้ว่าโค้ดที่เก่าที่สุดถูกเขียนโดยคนที่เก่งที่สุด ภายใต้แรงกดดันด้านเวลาที่น้อยกว่า
      บริษัทปัจจุบันของฉันก็เป็นแบบนั้น โค้ดช่วงแรกผู้ก่อตั้งเป็นคนเขียน และโค้ดใหม่บางส่วนเขียนโดยผู้รับเหมาที่มีเส้นตายกระชั้นชิด
    • บทความนี้นำข้อมูลที่น่าสนใจจากโปรเจ็กต์และภาษาที่เฉพาะเจาะจงและผิดปกติมาก รวมถึงวัฒนธรรมที่เฉพาะเจาะจงและผิดปกติมาก แล้วสรุปแบบเหมารวมอย่างหนักเป็นตัวเลขที่ฟังดูเด็ดขาดกับโค้ดทั้งหมด
      ถ้าข้อสรุปว่า “ยกตัวอย่างเช่น หากอิงอายุเฉลี่ยของช่องโหว่ โค้ดที่มีอายุ 5 ปีจะมีความหนาแน่นของช่องโหว่น้อยกว่าโค้ดใหม่ 3.4 เท่า และหากใช้อายุที่สังเกตได้ใน Android และ Chromium ก็จะน้อยกว่า 7.4 เท่า” เป็นจริง นั่นแปลว่าถ้าเขียนโค้ด C ที่เต็มไปด้วยบั๊กแล้วเก็บทิ้งไว้ออฟไลน์ 5 ปี มันจะปลอดภัยขึ้นอย่างนั้นหรือ?
      งานวิจัยนี้มีข้อมูลสำคัญอยู่ และก็มีความจริงบางอย่างใต้สิ่งที่แบ่งปันมา แต่ความมั่นใจที่ไร้หลักฐานรองรับและการขยายความเกินเลยนั้นชวนขัดใจมาก
  • “ประสิทธิภาพที่ดีขึ้น: การเขียนโค้ดอย่างปลอดภัยย้ายการตรวจพบบั๊กไปทางซ้ายก่อน code check-in ทำให้ความถูกต้องของโค้ดและประสิทธิภาพของนักพัฒนาดีขึ้น การเปลี่ยนแปลงนี้สะท้อนออกมาในตัวชี้วัดอย่างอัตราการ rollback เช่น การย้อนโค้ดฉุกเฉินจากบั๊กที่ไม่คาดคิด”
    “ทีม Android สังเกตว่าอัตรา rollback ของการเปลี่ยนแปลงที่เขียนด้วย Rust ต่ำกว่า C++ ไม่ถึงครึ่ง”
    ฉันเขียนโค้ดโปรดักชันขนาดใหญ่ด้วยหลายภาษามา 20 ปี แต่พอค้นพบ Rust ในปี 2016 ก็รู้เลยว่านี่คือภาษาที่ฉันจะทุ่มตัวให้กับมัน วันนั้นฉันซื้อหนังสือของ Klabnik กับ Carol ทันที และจนถึงตอนนี้ก็ยังมีฉบับกระดาษอยู่
    พูดตามตรงคือมันปลุกความรักในการเขียนโปรแกรมของฉันกลับมาอีกครั้ง

    • เข้าใจได้ เพราะสาเหตุใหญ่ที่สุดที่ฉันต้อง rollback คอมมิต C++ คือโปรแกรม crash จากการลืมเช็ก null pointer แบบโง่ ๆ ถ้า Rust กันปัญหาการเขียนโค้ดงี่เง่าประเภทนั้นและปัญหาคล้ายกันได้ rollback ประเภทหนึ่ง ก็ย่อมหายไปทั้งก้อน
  • ในบทความพูดถึง “ภาษาแบบ memory-safe (MSL)” ในรูปพหูพจน์ แต่ภาษาที่ระบุชัดว่าเป็นเป้าหมายการย้ายและกำลังปรับปรุง interoperability ด้วยกันมีแค่ Rust เท่านั้น
    Kotlin ก็ถูกพูดถึงในบริบทของการปรับปรุง Rust<>Kotlin interoperability และก็มีความสามารถด้าน memory safety อยู่ระดับหนึ่ง แต่ไม่แน่ใจว่าอยู่ในระดับเดียวกับ Rust หรือเปล่า เลยสงสัยว่า Google ใช้แค่สองภาษานี้ หรือกำลังหมายรวมภาษาอื่นด้วย

    • คนที่สนใจประเด็นนี้ โดยเฉพาะในช่วงไม่กี่ปีที่ผ่านมา มักชอบกรอบคิดแบบ “ภาษาแบบ memory-safe” กับ “ภาษาแบบ memory-unsafe”
      เพราะโดยพื้นฐานแล้วการปลอดภัยโดยค่าเริ่มต้นหรือไม่ต่างหากคือรากของปัญหา เป็นถ้อยคำที่ใช้เพื่อโฟกัสไปที่สาเหตุเชิงรากฐาน มากกว่าจะชี้นิ้วหรือแนะนำภาษาใดภาษาหนึ่ง
      สำหรับ Android ซึ่งเป็นหัวข้อของบทความนี้ ฉันไม่ค่อยรู้จักความพยายามย้ายไปยังภาษา memory-safe อื่นนอกจากสองตัวนี้ แม้จะไม่ได้ตามงานพัฒนา Android ทั้งหมด แต่ก็อ่านบทความแนวนี้ค่อนข้างสม่ำเสมอ และไม่จำได้ว่าเคยเห็นพูดถึงภาษาอื่นนอกจาก Rust หรือ Kotlin
    • ไม่ใช่เรื่องของ Rust อย่างเดียว การเขียนบริการเครือข่ายที่เป็น C ใหม่ด้วย Java, Python, Go ก็เป็นตัวอย่างของ การย้ายไปสู่ภาษา memory-safe เหมือนกัน
      แก่นสำคัญคือโค้ดของคุณจะไม่โดนช่องโหว่ด้าน memory safety ถ้าไม่ได้จำเป็นจริง ๆ อาจดีกว่าถ้าเลือกภาษาที่ไม่มีการจัดการหน่วยความจำแบบ manual ตามสไตล์ Rust
    • Android เคยพูดถึงภาษา memory-safe ที่ใช้อยู่ไว้อย่างละเอียดกว่าในบล็อกโพสต์ก่อนหน้านี้: https://security.googleblog.com/2022/12/memory-safe-language...
      Google ก็เผยแพร่มุมมองเรื่อง memory safety ไว้ที่ https://security.googleblog.com/2024/03/secure-by-design-goo... และพูดถึงภาษา memory-safe ที่ใช้อยู่ เช่น Java, Go, Rust ด้วย
    • มีภาษา memory-safe อยู่มาก และ Google ก็ใช้หลายภาษา เช่น Rust, Python, Java, Go เพียงแต่โค้ดระดับล่างของ Android ในทางประวัติศาสตร์นั้นเป็น C++ และตัวแทนหลักที่เป็น memory-safe สำหรับงานใหม่ในพื้นที่นั้นก็คือ Rust
    • Java กับ Kotlin ใช้กับแอป ส่วน Rust ใช้กับ system software ใหม่
      ในภาพรวมทั้ง Google นั้น Go ถูกใช้กับ system software บางส่วน แต่ฉันไม่เคยเห็นว่ามันถูกใช้ใน Android
  • ถ้าอายุของช่องโหว่เป็นไปตามการแจกแจงแบบเอ็กซ์โปเนนเชียล ตรรกะก็คือการโฟกัสกับ ค่าเริ่มต้นที่ปลอดภัย อย่าง memory safety ในโค้ดใหม่มีคุณค่าแบบไม่สมส่วน ทั้งในทางทฤษฎีและจากข้อมูล 6 ปีของ codebase Android
    น่าประหลาดใจ นี่เป็นครั้งแรกที่ฉันเห็นข้ออ้างแบบนี้ถูกใช้เพื่อสนับสนุน safe guardrail ที่ดึงความปลอดภัยให้ไปทางซ้าย และมันยอดเยี่ยมมาก มีประโยชน์เป็นพิเศษกับ codebase legacy ขนาดใหญ่ที่อาจมีคนพูดว่า “เราไม่ได้ประโยชน์จาก memory safety กับโค้ด C++ legacy 100 ล้านบรรทัดอยู่แล้ว แล้วจะทำไปทำไม”
    มันยังดูเหมือนจะหมายความว่าการตรวจจับช่องโหว่แบบเบา ๆ ก็ให้ผลตอบแทนที่มากเกินสัดส่วนได้เช่นกัน แม้จะดูแค่โค้ดใหม่และ dependency ใหม่ ไม่ใช่ backlog ทั้งหมด

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

    • โค้ดเก่าก่อนหน้านี้ก็ไม่ได้ถูกตรวจอย่างจริงจังนักอยู่แล้ว และผมไม่คิดว่าจุดนั้นเปลี่ยนไป
      บทความไม่ได้เสนอทฤษฎีว่าทำไมโค้ดเก่าถึงมีบั๊กน้อยกว่า แต่ความเห็นของผมเรียบง่ายมาก: เพราะมันถูกพบไปแล้ว
      ถ้าสมมติว่าโค้ดใด ๆ มีจำนวนบั๊กที่ยังไม่รู้คงที่ต่อ 1000 บรรทัด เมื่อเวลาผ่านไป โค้ดนั้นก็จะถูกใช้งานในโปรดักชันด้วยอินพุตที่หลากหลายมากขึ้น ทำให้โอกาสถูกค้นพบนั้นเพิ่มขึ้น และเมื่อผ่านการแก้ไขรวมถึง code review ในกระบวนการนั้น โดยเฉลี่ยก็ควรคาดหวังได้ว่ามันจะดีขึ้น
      ดังนั้นเมื่อเวลาผ่านไป จำนวนบั๊กต่อ 1000 บรรทัดในโค้ดเดิมจึงลดลง เท่ากับว่าได้ผ่าน การพิสูจน์ในสนามจริง มาแล้ว
      อย่างที่บทความบอก ถ้ายังเพิ่มบั๊กใหม่เข้ามาด้วยอัตราเท่าเดิมต่อไปก็จะไม่มีความคืบหน้า แต่ถ้าภาษาแบบ memory-safe ทำให้เกิดบั๊กในฟีเจอร์ใหม่น้อยลง จำนวนบั๊กทั้งหมดก็น่าจะลดลงตามเวลา
    • ผมไม่ค่อยเข้าใจประเด็นนี้นัก สิ่งที่ถูกตรวจคือ Android และผู้คนค้นหาช่องโหว่ทั้งแบบ manual และแบบอัตโนมัติโดยอาศัยซอร์สโค้ดกับไบนารี ไม่ใช่ commit log ผมเลยไม่เข้าใจว่า commit log เกี่ยวอะไรกับการหาบั๊ก
      commit มีไว้เพื่อระบุว่าเป็นผลงานของใครเท่านั้น ถ้าไลบรารีเก่าที่ไม่เปลี่ยนมา 20 ปีผ่านทั้งการ fuzzing และการตรวจโค้ดด้วยมือมา 20 ปี ก็มีโอกาสสูงว่ามันจะแข็งแรงพอสมควร
    • ผมยังไม่ค่อยพอใจกับข้อสรุปที่ว่าโค้ดเก่ามีช่องโหว่น้อยกว่าเต็มที่นัก นอกจากอายุแล้วอาจมีปัจจัยอื่นที่อธิบายความต่างนี้ได้
      ตัวอย่างเช่น ในช่วงไม่กี่ปีที่ผ่านมา วิศวกรอาจมุ่งเขียนส่วนที่เสี่ยงที่สุดใหม่ด้วยภาษาแบบ memory-safe ขณะที่โค้ดเก่าที่เสี่ยงต่ำกว่าถูกแก้น้อยกว่า
      หรืออาจมีการเปลี่ยนแปลงด้านกระบวนการหรือบุคลากรที่ทำให้ข้อบกพร่องเพิ่มขึ้นก็ได้
      ถึงอย่างนั้น คำอธิบายที่ว่าแต่ละบั๊กมีความน่าจะเป็นที่จะถูกพบต่อหน่วยเวลา และเมื่อเวลาผ่านไปจำนวนข้อบกพร่องที่เหลือจะลดลง ก็ฟังดูสมเหตุสมผล ถ้าผู้ดูแลแก้ช่องโหว่ได้มากกว่าที่เพิ่มเข้ามาใหม่ โค้ดเก่าก็น่าจะมีช่องโหว่น้อยลง และช่องโหว่ที่เหลือก็น่าจะเป็นพวกที่หาเจอยากกว่า
    • สิ่งที่น่าสนใจไม่ใช่ช่องโหว่ในเชิงทฤษฎี แต่คือช่องโหว่ที่ถูกนำไปใช้โจมตีจริง ถ้าผู้โจมตีไม่พยายามหาช่องโหว่ในโค้ดชุดใด ชุดนั้นก็แทบไม่ต่างจากการไม่มีอยู่จริง
  • ด้วยความที่โค้ดใหม่บน Mac ส่วนใหญ่เขียนด้วย Swift ซึ่งเป็นภาษาแบบ memory-safe ขณะที่ Windows ยังใช้ C หรือ C++ เป็นหลัก ผมเลยสงสัยว่าตรรกะนี้จะนำไปใช้กับ Mac และ Windows ได้อย่างไร

    • Apple ยังเพิ่มโค้ด Objective-C จำนวนมากใน macOS เวอร์ชันใหม่ ๆ อยู่ [0]
      ผมหาตัวเลขล่าสุดเรื่องสัดส่วนการใช้ภาษาใน Windows เวอร์ชันใหม่ไม่เจอ แต่ Microsoft กำลังใช้ Rust ทั้งกับการพัฒนาใหม่และการเขียนฟีเจอร์เดิมใหม่ [1] [2]
      [0] ดูหัวข้อ “Evolution of the programming languages” https://blog.timac.org/2023/1128-state-of-appkit-catalyst-sw...
      [1] https://www.theregister.com/2023/04/27/microsoft_windows_rus...
      [2] https://www.theregister.com/2024/01/31/microsoft_seeks_rust_...
    • มีข้อมูลไหมว่า Windows ยังใช้ C หรือ C++ เป็นหลัก? ความรู้สึกของผมคือทุกวันนี้งานพัฒนา Windows จำนวนไม่น้อยเป็น C# แล้ว ตอนผมอยู่ EA เกือบ 15 ปีก่อน เครื่องมือภายในก็เอนมาทาง C# อย่างชัดเจนแล้ว
  • ถ้าคิดต่อไปถึงช่วงปลายเกม เมื่อช่องโหว่กลายเป็นของหายาก มันก็จะยิ่งมีมูลค่าสูงขึ้น ช่องโหว่ที่เหลือจะถูกกักตุนอย่างเข้มงวดโดยรัฐชาติ และใช้กับเป้าหมายมูลค่าสูงอย่างประหยัด
    ถ้าบล็อกโพสต์นี้อธิบายยุคที่ 4 อยู่ ยุคที่ 5 อาจคล้ายกับ Lockdown Mode ของ iOS คือให้ผู้ใช้ที่กังวลเรื่องความปลอดภัยสามารถติ๊กช่องเพื่อเพิ่มความปลอดภัยโดยยอมแลกกับประสิทธิภาพที่ลดลง
    ช่องติ๊กในอุดมคติคือแบบที่ตรวจจับและจับการโจมตีได้ด้วยวิธีอย่าง virtualization จากนั้นส่งต่อให้ทีมความปลอดภัยวิเคราะห์ สิ่งนี้จะเป็นแรงยับยั้งผู้โจมตี เพราะพวกเขาคงไม่อยากเผาช่องโหว่หายากไปกับสถานการณ์ที่ผู้ใช้อาจเปิดช่องติ๊กความปลอดภัยนั้นไว้ และเป้าหมายมูลค่าสูงจำนวนมากก็น่าจะเปิดมัน
    นี่คือ ภูมิคุ้มกันหมู่ สำหรับช่องโหว่ซอฟต์แวร์ ไม่ใช่เชื้อโรคทางชีวภาพ
    ผู้ใช้ที่ใส่ใจความปลอดภัยสูงก็มักมีแนวโน้มจะใส่ใจความเป็นส่วนตัวสูงด้วย ดังนั้นแทนที่จะส่งกิจกรรมของผู้ใช้ทั้งหมดออกไปแบบเงียบ ๆ ก็ควรแสดงการแจ้งเตือนให้ผู้ใช้รู้เมื่อพบการโจมตี การแสดงเพียงข้อมูลกิจกรรมเครือข่ายที่ผิดปกติไม่กี่ KB ก็น่าจะพอให้ทีมความปลอดภัยนำไปประกอบการวิเคราะห์ย้อนกลับการโจมตีได้ และควรขอความยินยอมจากผู้ใช้ก่อนแชร์