1 คะแนน โดย GN⁺ 2024-03-01 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • แคมเปญ repo confusion (การสับสนรีโพซิทอรี) ที่เริ่มขึ้นช่วงกลางปี 2023 กลับมาระบาดอีกครั้ง โดยตรวจพบรีโพซิทอรีมากกว่า 100,000 รายการบน GitHub ที่มีเพย์โหลดอันตรายในลักษณะคล้ายกัน
  • ผู้โจมตีสร้างสำเนาอันตรายที่ดูคล้ายรีโพซิทอรีปกติเพื่อหลอกให้นักพัฒนาสับสน และผสมผสานการคัดลอก, การฝัง loader, การอัปโหลดซ้ำ, การ fork จำนวนมาก และการโปรโมตแบบแอบแฝง
  • เมื่อรันรีโพซิทอรีอันตราย เพย์โหลดจะผ่านการ obfuscation 7 ชั้น ก่อนดาวน์โหลดโค้ด Python และไบนารีลงมา จากนั้นขโมยข้อมูลอ่อนไหว เช่น ข้อมูลล็อกอิน, รหัสผ่านเบราว์เซอร์ และคุกกี้
  • แม้ GitHub จะลบ fork ส่วนใหญ่อัตโนมัติ แต่รีโพซิทอรีที่หลบการตรวจจับและรายการที่อัปโหลดด้วยมือยังคงอยู่ หาก เหลือรอดเพียง 1% ก็ยังทำให้มีรีโพซิทอรีอันตรายหลายพันรายการคงอยู่
  • กระแสการโจมตีย้ายจากแพ็กเกจอันตรายบน PyPI ไปยังรีโพซิทอรี GitHub ทำให้ software supply chain นอก package manager กลายเป็นพื้นผิวโจมตีโดยตรงด้วย

วิธีโจมตีแบบ repo confusion

  • repo confusion คล้ายกับ dependency confusion ตรงที่หลอกให้ผู้ใช้ดาวน์โหลดรีโพซิทอรีอันตรายแทนรีโพซิทอรีปกติ
  • ความต่างอยู่ที่จุดที่ถูกใช้โจมตี
    • dependency confusion ใช้ประโยชน์จากวิธีทำงานของ package manager
    • repo confusion อาศัยสถานการณ์ที่มนุษย์เลือกรีโพซิทอรีผิดเพราะหน้าตาคล้ายกัน
  • แคมเปญนี้เพิ่มโอกาสติดเชื้อด้วยการกระจายรีโพซิทอรีอันตรายจำนวนมากบน GitHub
    • คัดลอกรีโพซิทอรีเดิม เช่น TwitterFollowBot, WhatsappBOT, discord-boost-tool, Twitch-Follow-Bot
    • ฝัง malware loader ลงในสำเนา
    • อัปโหลดกลับขึ้น GitHub ด้วยชื่อเดิม
    • fork แต่ละรีโพซิทอรีแบบอัตโนมัติหลายพันครั้ง
    • โปรโมตอย่างแอบแฝงบนฟอรัมและ Discord เป็นต้น

ลำดับเหตุการณ์หลังรันรีโพซิทอรีอันตราย

  • เมื่อผู้ใช้ใช้งานรีโพซิทอรีอันตราย เพย์โหลดที่ซ่อนอยู่จะคลาย obfuscation 7 ชั้น
  • หลังจากนั้นจะดึงโค้ด Python อันตรายและไฟล์ปฏิบัติการไบนารีมา
  • โค้ดอันตรายส่วนใหญ่อิงจากเวอร์ชันที่ดัดแปลงของ BlackCap-Grabber
  • เป้าหมายที่ถูกเก็บรวบรวมคือข้อมูลรับรองการล็อกอินของหลายแอป, รหัสผ่านและคุกกี้ในเบราว์เซอร์ รวมถึงข้อมูลลับอื่นๆ
  • ข้อมูลที่ถูกขโมยจะถูกส่งไปยังเซิร์ฟเวอร์ C&C (command-and-control) ของผู้โจมตี และตามด้วยกิจกรรมอันตรายเพิ่มเติม
  • สามารถดูการวิเคราะห์โค้ดที่เกี่ยวข้องได้ใน technical analysis ของ Trend Micro

การลบอัตโนมัติของ GitHub และรีโพซิทอรีที่ยังเหลืออยู่

  • GitHub ตรวจจับ automation และลบรีโพซิทอรีที่ถูก fork ส่วนใหญ่ได้อย่างรวดเร็ว
  • อย่างไรก็ตาม การตรวจจับ automation ยังพลาดรีโพซิทอรีจำนวนมาก และรีโพซิทอรีที่อัปโหลดด้วยมือยังคงอยู่
  • เนื่องจาก attack chain ถูกทำให้เป็นอัตโนมัติในขนาดใหญ่ แม้ เหลือเพียง 1% ก็ยังกลายเป็นรีโพซิทอรีอันตรายหลายพันรายการ
  • หากค้นหา 🔥 2024 language:python บน GitHub จะเห็นรีโพซิทอรีบางส่วนที่กำลังแพร่กระจายในปัจจุบัน
  • หากรวมรีโพซิทอรีที่ถูกลบแล้ว ขนาดโดยรวมจะสูงถึงหลายล้านรายการ
    • โดยปกติการลบจะเกิดขึ้นไม่กี่ชั่วโมงหลังอัปโหลด ทำให้บันทึกเป็นเอกสารได้ยาก
    • รีโพซิทอรีต้นทางจำนวนมากยังคงอยู่ และการลบมักมุ่งเป้าไปที่ fork bomb เป็นหลัก
    • ตัวอย่างเช่น ใน รายการรีโพซิทอรีของ Mattia69 จะเห็น fork หลายพันรายการในส่วนสรุป แต่ไม่ปรากฏใน รายละเอียด fork
  • เมื่อผู้ใช้บางราย fork รีโพซิทอรีอันตรายโดยไม่รู้ตัว จึงเกิด ผลกระทบเครือข่ายจาก social engineering ขั้นที่สอง ด้วย

ช่วงเวลาการดำเนินแคมเปญ

  • พฤษภาคม 2023: Phylum รายงาน แพ็กเกจอันตรายที่ถูกอัปโหลดขึ้น PyPI
    • แพ็กเกจเหล่านี้มีส่วนต้นของเพย์โหลดปัจจุบัน
    • แพร่กระจายผ่านการเรียก os.system("pip install package") ที่ถูกฝังใน fork ของรีโพซิทอรียอดนิยมบน GitHub เช่น chatgpt-api
  • กรกฎาคม~สิงหาคม 2023: มีรีโพซิทอรีอันตรายหลายรายการถูกอัปโหลดขึ้น GitHub และส่งเพย์โหลดโดยตรงแทนการดึงแพ็กเกจจาก PyPI
    • เป็นการเปลี่ยนแปลงหลังจาก PyPI ลบแพ็กเกจอันตรายและชุมชนความปลอดภัยให้ความสนใจมากขึ้น
    • Aliakbar Zahravi และ Peter Girnus จาก Trend Micro เผยแพร่ การวิเคราะห์ทางเทคนิค
  • พฤศจิกายน 2023~ปัจจุบัน: ตรวจพบรีโพซิทอรีมากกว่า 100,000 รายการที่มีเพย์โหลดอันตรายคล้ายกัน และจำนวนยังเพิ่มขึ้นต่อเนื่อง
  • เหตุผลที่วิธีนี้เป็นประโยชน์ต่อผู้โจมตีชัดเจน
    • GitHub มีขนาดใหญ่มาก แม้อินสแตนซ์จำนวนมากก็ยังดูเล็กเมื่อเทียบสัดส่วน จึงตรวจจับได้ยาก
    • ต่างจากเดิม ไม่มี package manager เข้ามาเกี่ยวข้อง จึงไม่เหลือชื่อแพ็กเกจอันตรายที่ชัดเจนเป็นตัวชี้วัด
    • รีโพซิทอรีเป้าหมายอยู่ในกลุ่มเฉพาะขนาดเล็กและมีความนิยมต่ำ ทำให้นักพัฒนามีโอกาส clone รีโพซิทอรีปลอมอันตรายผิดได้ง่าย

การย้ายจาก package manager ไปยัง SCM

  • การย้ายจากแพ็กเกจอันตรายบน PyPI ไปยังรีโพซิทอรีอันตรายบน GitHub สอดคล้องกับแนวโน้มที่สังเกตพบในหลาย package manager และแพลตฟอร์ม SCM
  • กล่าวได้ว่าเมื่อชุมชนความปลอดภัยโฟกัสที่ package manager มากขึ้น เส้นทางโจมตีก็ย้ายไปที่อื่น
  • GitHub และแพลตฟอร์มลักษณะเดียวกันสร้างบัญชีและรีโพซิทอรีแบบอัตโนมัติได้ง่าย มี API ที่สะดวก และมี rate limit ที่ค่อนข้างหลวมซึ่งหลบเลี่ยงได้ง่าย
  • เนื่องจากสามารถซ่อนตัวท่ามกลางรีโพซิทอรีจำนวนมหาศาล SCM จึงกลายเป็นเป้าหมายที่เหมาะสำหรับการแอบติดเชื้อ software supply chain
  • แคมเปญ dependency confusion, โค้ดอันตรายใน package registry และการแพร่กระจายโค้ดอันตรายผ่าน SCM แสดงให้เห็นว่า แม้จะมีเครื่องมือและกลไกความปลอดภัยจำนวนมาก ความปลอดภัยของ software supply chain ก็ยังเปราะบาง

ตัวชี้วัดสำหรับตรวจสอบว่าติดเชื้อหรือไม่

  • ควรค้นหารูปแบบต่อไปนี้ในโค้ด Python และตรวจสอบรายการที่ตรงกัน
    • exec(Fernet
    • exec(requests
    • exec(__import
    • exec(bytes
    • exec("""\nimport
    • exec(compile
    • __import__("builtins").exec(
  • ควรตรวจสอบว่ามีรีโพซิทอรีเกี่ยวกับ automation บนแพลตฟอร์มโซเชียล, bot หรือเกมอยู่ในเครื่องหรือไม่ และลบออก
  • หากจำเป็นต้องใช้จริง ให้ติดตั้งใหม่ แต่ควรตรวจสอบแหล่งที่มาอย่างรอบคอบ หรือรันใน sandbox
  • หากมีความเป็นไปได้ว่าเคย clone รีโพซิทอรีประเภทนี้ ควรถือว่าคุกกี้, ข้อมูลรับรอง และคีย์ต่อไปนี้ถูกขโมยไปแล้ว และตอบสนองตามนั้น
    • เบราว์เซอร์: บริการการเงิน, บริการอีเมล, บริการคริปโท, Amazon, eBay, AliExpress, Facebook, Instagram, Twitter, Youtube, Discord, TikTok, Telegram, Twitch, Steam, Yahoo, ExpressVPN, Spotify, บริการสตรีมมิง
    • แอป: Exodus, Atomic Wallet, Guarda, Coinomi, Ethereum
  • รายการ checksum ของไฟล์ทั้งหมดจัดการในทางปฏิบัติได้ยาก แต่สามารถดูรายการร่วมบางส่วนได้ที่ VirusTotal graph
  • หลังได้รับการแจ้งเตือน Cloudflare ได้ปิดใช้งาน DNS record ของที่อยู่อันตรายที่พบ

การป้องกันและการตอบสนอง

  • GitHub ได้รับการแจ้งเตือนแล้วและลบรีโพซิทอรีอันตรายส่วนใหญ่แล้ว แต่แคมเปญยังคงดำเนินต่อไป
  • การโจมตีที่พยายามฝังโค้ดอันตรายใน supply chain กำลังแพร่หลายมากขึ้นเรื่อยๆ
  • มีโซลูชันมากมายที่ตรวจจับมัลแวร์ในระดับระบบและเครือข่าย แต่ supply chain ยังคงเป็นพื้นผิวโจมตีที่ใหญ่และทำกำไรได้สำหรับผู้โจมตี
  • หากพบรีโพซิทอรีอันตราย ไม่ว่าจะเป็นส่วนหนึ่งของแคมเปญนี้หรือไม่ สามารถรายงานผ่าน abuse or spam report ของ GitHub ได้
  • Apiiro สร้างระบบตรวจจับโค้ดอันตรายที่มอนิเตอร์ codebase ที่เชื่อมต่ออยู่
  • หากไม่มอนิเตอร์เพย์โหลดอันตรายที่ถูกฝังเข้ามา ความปลอดภัยขององค์กรจะต้องพึ่งพาเงื่อนไขอย่างความสามารถของนักพัฒนาในการไม่เลือกรีโพซิทอรีผิดที่แทบเหมือนกัน, การไม่มีข้อผิดพลาดใดๆ ในการตั้งค่า CI/CD และโค้ดจากบุคคลที่สามที่ปลอดภัย 100%
  • จำเป็นต้องมีแนวทางที่ก้าวข้ามการตรวจจับและรวบรวมช่องโหว่ทั่วไป เพื่อเผยให้เห็นความเสี่ยงของ software supply chain และแอปพลิเคชันรุ่นถัดไป

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

 
GN⁺ 2024-03-01
ความคิดเห็นจาก Hacker News
  • นอกเหนือจากคำเตือนทั่วไปว่าควรระวังโค้ดที่นำมาจากรีโพสาธารณะหรือแหล่งภายนอก และต้อง ตรวจสอบ dependency tree แล้ว ก็สงสัยว่าหากมีโค้ดประสงค์ร้ายจำนวนมากอยู่ในรีโพสาธารณะ มันจะส่งผลอย่างไรต่อ LLM และเครื่องมืออัตโนมัติที่ฝึกจากเนื้อหาเหล่านั้น
    ดูเหมือนมีความเป็นไปได้ที่ส่วนประสงค์ร้ายจะบังเอิญปะปนเข้าไปเมื่อเครื่องมืออย่าง Copilot สร้างคำตอบโค้ดยาว ๆ
    ช่องโหว่ง่าย ๆ อย่าง injection ก็พบเห็นกันบ่อยอยู่แล้ว

    • สิ่งที่น่ากังวลยิ่งกว่าการที่แบ็กดอร์บังเอิญเข้าไปอยู่ในผลลัพธ์ของ LLM คือการที่ หน่วยข่าวกรอง ฝังแบ็กดอร์ไว้ในผลลัพธ์ของ LLM
      ตอนนี้อาจยังไม่ใช่ แต่ดูเหมือนว่าในอีกไม่กี่ปีก็เป็นไปได้มากพอ
    • LLM ไม่เพียงแต่นำโค้ดที่มีช่องโหว่จากข้อมูลอินพุตมาวางต่อเท่านั้น แต่ดูเหมือนจะสร้าง ช่องโหว่ใหม่ ขึ้นเองได้ด้วย
      AI ไม่ได้ให้หลักประกันใด ๆ เรื่องความถูกต้อง
    • เพิ่งโพสต์ประเด็นเกี่ยวกับ LLM ที่เกี่ยวกับการยึดบอตแปลง safetensors ของ Hugging Face: https://news.ycombinator.com/item?id=39549482
      แสดงให้เห็นว่าผู้โจมตีสามารถยึดบอตบริการที่เชื่อมกับ Hugging Face Safetensors Conversion Space ได้ ซึ่งเป็นบริการยอดนิยมที่ใช้แปลงโมเดลแมชชีนเลิร์นนิงที่ไม่ปลอดภัยในระบบนิเวศให้เป็นเวอร์ชันที่ปลอดภัยกว่า
    • เป็นความเสี่ยงจริง แต่คล้ายกับความเสี่ยงที่เมื่อยอมรับ PR ของเพื่อนร่วมงานโดยไม่รีวิว อาจมี โค้ดที่มีช่องโหว่ ซึ่งคัดลอกมาจากที่ไหนสักแห่งหลุดเข้ามา
      ถ้าจะใช้ LLM ก็ต้องลงทุนลงแรงกับการรีวิวโค้ดมากขึ้น และมองว่าการแลกเปลี่ยนนี้คุ้มค่า
    • จำนวนตัวอย่างที่ตรวจพบในแคมเปญนี้มีมากมาก จึงเป็นความเสี่ยงที่สมจริงกว่าที่คิด
      อย่างไรก็ตาม หากจะนำไปสู่อุบัติเหตุจริง โดยหลัก ๆ มีอุปสรรคสองอย่าง: ตัวสร้างมักได้รับคำสั่งภายในให้หลีกเลี่ยงโค้ดแบบนั้น และด้วยธรรมชาติของ LLM โอกาสที่จะทำซ้ำที่อยู่ของผู้โจมตีจริง ๆ แบบเดิมนั้นต่ำ
      ถึงอย่างนั้น attack vector ต่าง ๆ เช่น bind shell, denial of service และการรั่วไหลในภาคสนามก็ยังคงอยู่
  • GitHub กำลังล้มเหลวในลักษณะคล้ายกับที่ Usenet เคยล้มเหลว
    ใคร ๆ ก็สร้างรีโพได้ และไม่มีสิ่งใดช่วยแยกระหว่างรีโพทางการกับรีโพสแปม
    เหมือนกับที่ Amazon ตั้งเป้าเป็น “ร้านค้าของทุกสิ่ง” แต่ไปเจอกับความจริงว่า “90% ของทุกสิ่งคือขยะ” จนกลายเป็นร้านค้าที่ส่วนใหญ่เป็นขยะ GitHub เองก็ต้องตัดสินใจว่าผลิตภัณฑ์ของตนคือ “รีโพสำหรับทุกคน” หรือ “โค้ดที่เชื่อถือได้”
    ตัวอย่างเช่น แม้แต่ PG JDBC ทางการก็ดูไม่มีองค์ประกอบใดที่สแปมเมอร์เลียนแบบไม่ได้ แล้วจะเชื่อได้อย่างไรว่านี่ไม่ใช่รีโพที่ติดเชื้อ: https://github.com/pgjdbc

    • ดูเหมือนว่า GitHub เลือกเป็น รีโพสำหรับทุกคน ไปแล้วตั้งแต่เริ่มบริษัทเมื่อ 16 ปีก่อน
    • ถ้าเป็นไลบรารี Java โดยปกติจะดาวน์โหลดจาก Maven Central ไม่ใช่ GitHub
      Sonatype กำหนดให้พิสูจน์ความเป็นเจ้าของโดเมนแบบย้อนกลับที่ใช้ใน groupId ซึ่งในกรณีนี้คือ org.postgresql
      วิธีทำอยู่ที่นี่: https://central.sonatype.org/faq/how-to-set-txt-record/
      ถ้าต้องการความมั่นใจยิ่งขึ้น ก็สามารถตรวจสอบลายเซ็น GPG ได้ เพราะ artifact ทั้งหมดที่เผยแพร่บน Maven Central จะถูกเซ็นไว้ แต่ข้อเสียคือต้องได้คีย์ที่ Postgres ใช้เซ็นผ่านช่องทางที่เป็นอิสระจาก Sonatype
      ในกรณีของ PG ลองค้นหาเร็ว ๆ แล้วยังไม่พบคีย์
    • ดูเหมือนว่าหลายคนยังไม่ค่อยรู้สึกว่าตัวเลขนี้เล็กแค่ไหน
      GitHub มีรีโพประมาณ 500 ล้านรีโพ ดังนั้นระดับนี้จริง ๆ แล้วถือว่าค่อนข้างดี
    • รีโพติดเชื้อมากกว่า 100,000 รายการไม่ใช่เรื่องดี แต่ก็ไม่ได้หมายความว่า GitHub ล้มเหลว
      ถ้าเป็นนักพัฒนาที่จะเอารีโพติดเชื้อไปใช้ ต่อให้ไม่มีรีโพแบบนั้นบน GitHub ก็คงหาวิธีอื่น ๆ อีกมากมายในการสร้างผลิตภัณฑ์ที่ไม่ปลอดภัยได้อยู่ดี
    • หากพิสูจน์ความเป็นเจ้าของโดเมน ก็สามารถได้รับ ป้ายยืนยัน บนหน้าองค์กร และเพิ่มความน่าเชื่อถือได้มาก
      องค์กรที่ยกมาเป็นตัวอย่างดูเหมือนแค่ไม่ได้ทำสิ่งนั้น
  • ปัญหา supply chain นี่ปวดหัวจริง ๆ
    แม้จะไม่ได้เล็ง npm release โดยตรง แต่ผมกำลังสร้าง npm release เพื่อใช้ socket.dev มอนิเตอร์โปรเจกต์เว็บเบราว์เซอร์เวอร์ชวลไลเซชันน้ำหนักเบาที่ชื่อ BrowserBox
    โปรเจกต์นี้ก็มี dependency รวม sub-dependency ทั้งหมดราว 800 ตัว ทั้งที่ใช้ dependency ระดับบนสุดแค่ 19 ตัว และเมื่อเทียบกับทั้งสแตกแล้วก็ถือว่าค่อนข้างเบา
    ตอนนี้กำลังคิดอยู่ว่าจะ snapshot dependency ทั้ง 800 ตัวไว้ใน namespace @browserbox ของ npm แล้วไล่ติดตามและแพตช์ช่องโหว่ที่พบดีไหม
    ฟังดูเหมือนบ้า แต่สถานการณ์ตอนนี้เป็นแบบนั้น และอย่างน้อยถ้าทำแบบนั้นก็จะรับประกันช่องโหว่ supply chain ฝั่ง Node/JS ได้เองในระดับความปลอดภัยของบริษัท
    https://socket.dev
    https://github.com/BrowserBox/BrowserBox

    • ไม่รู้ว่า npm มีฟังก์ชันแบบเดียวกันมากแค่ไหน แต่ crates.io กับ cargo มีเครื่องมืออย่าง cargo audit และ cargo deny สำหรับตรวจ CVE ใน dependency tree ภายใน pipeline
      lock file เก็บ sha256 ของทั้ง tree ไว้ ดังนั้นต่อให้ repository ถูกแฮ็ก ก็ไม่จำเป็นต้อง mirror เพื่อป้องกันการเปลี่ยนแปลง
      การ pin ไว้ที่เวอร์ชันซึ่งช้ากว่าล่าสุดสักสองสามเดือน ดูเหมือนเป็นสมดุลที่พอดีระหว่างการหลีกเลี่ยง CVE ใหม่ ๆ กับการไม่ถูกล็อกอยู่กับเวอร์ชันเก่าเกินไปจนต้องแก้ครั้งใหญ่ทีเดียว
      จำนวนดาวน์โหลดน่าจะเป็นตัวชี้วัดที่พอใช้ได้เมื่อเทียบกับ dependency ระดับบนสุดที่มีวัตถุประสงค์คล้ายกัน แต่นี่ก็เป็นการตัดสินเชิงอัตวิสัย
      Austral ใช้ linear type เพื่อให้สิทธิ์แก่ dependency ได้อย่างละเอียด
      เช่น ไลบรารีกราฟิกไม่จำเป็นต้องมี file I/O และไลบรารีส่งข้อมูลผ่านเครือข่ายไม่จำเป็นต้องเข้าถึงไมโครโฟน
      มันเป็นแค่มาตรการบรรเทา แต่ก็อยากเห็นในภาษาอื่น ๆ ด้วย
    • คำว่า “dependency แค่ราว 800 ตัว” ฟังแล้วแอบขนลุก
      ราว 10 ปีก่อน หลังย้ายจาก .NET ไป Java ผมตกใจที่ต้องใช้เวลากับ dependency hell มากขึ้นมาก และทุกวันนี้ทั้งโปรเจกต์ Java และ Python ต่างก็ใช้เวลาไปกับการอัปเดตช่องโหว่และปัญหา dependency อย่างน่ากลัว
      เหตุผลที่ .NET มีปัญหานี้น้อยกว่า น่าจะเป็นเพราะการนำระบบจัดการแพ็กเกจอัตโนมัติเข้ามาค่อนข้างช้า และ NuGet เองก็ยังค่อนข้างใหม่ ตอนนั้นหลายโปรเจกต์จึงยังไม่ได้ใช้ ทำให้มีวัฒนธรรมที่หลีกเลี่ยง dependency tree แบบ transitive ขนาดใหญ่
      ปัญหาล่าสุดของ Boeing ก็ดูคล้ายกัน
      หลายทศวรรษที่ผ่านมา การผลิตถูกส่งต่อให้ซัพพลายเออร์ภายนอกมากขึ้นและมุ่งเน้นการปรับต้นทุนให้เหมาะสม ทำให้การจัดการ supply chain ยากขึ้นเรื่อย ๆ และเมื่อมองภาพใหญ่ก็คล้ายกับวัฒนธรรม supply chain ของวิศวกรรมซอฟต์แวร์สมัยใหม่
      ตอนที่ทำงานในบริษัทการเงินที่ห้ามใช้ package manager ด้วยเหตุผลด้านความปลอดภัยของ supply chain การจัดการ dependency กลับน่ารำคาญน้อยที่สุด และปัญหาคุณภาพก็น้อยที่สุดด้วย
      โค้ดที่ไม่มีวันเปลี่ยนเว้นแต่คุณจะเปลี่ยนอย่างชัดเจน มีข้อดีของมัน
      หลายส่วนที่คนอื่นอาจดึงแพ็กเกจมาใช้ เราก็ implement เองเป็นจำนวนมาก แต่เพราะทำเฉพาะสิ่งที่จำเป็นและใช้มาตรฐานโค้ดที่สูงกว่า จึงเข้าใจ ดีบัก และแก้ไขได้ง่าย
      ต้นทุนในการเขียนครั้งแรกเป็นค่าใช้จ่ายครั้งเดียวและ amortize ได้ดี แต่ต้นทุนซ้ำ ๆ ในการรับมือกับโค้ดที่พยายามทำทุกอย่างเพื่อทุกคนนั้นระยะยาวจะใหญ่กว่า และมักสะสมเพิ่มขึ้น
      “Simple Made Easy” ของ Rich Hickey แสดงปรากฏการณ์นี้ได้ดี สิ่งที่เรียบง่ายกับสิ่งที่ง่ายไม่เหมือนกัน และตัวเลือกที่เรียบง่ายอาจดูยากกว่าในช่วงแรก แต่เมื่อผลกระทบลำดับสองสะสมกัน ระยะยาวกลับง่ายกว่า
  • ผมสังเกตเรื่องนี้ได้อยู่แล้วตอนบังเอิญเห็น repository คล้าย ๆ กัน
    ปกติก็ไม่รันโค้ดจาก repository สุ่มอยู่แล้ว แต่ตอนนี้แม้จะเชื่อถือ repository และเจ้าของ ผมก็ยังเปิด sandbox VM
    ทุกวันนี้ถ้าเป็นนักพัฒนา ก็คงต้องแยกสภาพแวดล้อมอย่างน้อยสามแบบให้ชัดเจน คือ งาน งานอดิเรก และส่วนตัว

    • แค่คำพูดที่ว่านักพัฒนาควรแยกสภาพแวดล้อมงาน งานอดิเรก และส่วนตัว ก็แสดงให้เห็นแล้วว่าความซับซ้อนของชีวิตดิจิทัลเพิ่มขึ้นจนทำให้สงสัยว่าจะยั่งยืนในระยะยาวได้หรือไม่
    • ทุกปี Qubes ดูเหมือนจะเป็นตัวเลือกที่สมเหตุสมผลมากขึ้น
    • ตอนนี้ผมก็ทำแบบนี้เหมือนกัน ไม่ใช่แค่เพราะซอฟต์แวร์ที่อาจเป็นมัลแวร์เท่านั้น
      ยังมีโปรเจกต์ที่แม้ไม่ใช่มัลแวร์ แต่ถูกออกแบบหละหลวมหรือเขียนมาอย่างโง่ ๆ
      โปรแกรมหนึ่งที่ผมรันเมื่อไม่นานมานี้ เพิ่ม 3 บรรทัดลงใน ~/.bashrc ก่อนที่ผมจะสั่งให้ทำอะไรเสียอีก และผมเพิ่งรู้หลังจากนั้นหลายวัน
      ผมไม่เข้าใจว่านักพัฒนาคนไหนถึงคิดว่านี่เป็นไอเดียที่ดี และเพราะอย่างนั้น ตอนนี้ทุกครั้งที่รันโค้ดภายนอก ผมจึงใช้ sandbox
    • ฟังดูเป็นเหตุผลที่ดีในการใช้ Qubes OS ซึ่งทุกอย่างรันใน VM เป็นค่าเริ่มต้น
      มันเป็น OS ที่ผมใช้ประจำวัน
    • การไม่ปะปนสภาพแวดล้อมงานกับส่วนตัว น่าจะเป็นพื้นฐานที่สุดแล้วไม่ใช่หรือ
      มีนายจ้างที่อนุญาตเรื่องแบบนี้จริง ๆ เหรอ?
  • อยากรู้ว่าในที่ทำงานใช้เครื่องมืออะไรเพื่อหลีกเลี่ยงปัญหาแบบนี้ และพอใจกับการตั้งค่าปัจจุบันไหม
    กำลังพัฒนา SDK ที่มียอดดาวน์โหลดรายสัปดาห์สูงด้วยทีมค่อนข้างเล็ก และเคยประเมินโซลูชันอย่าง snyk, aikido.dev, โซลูชันที่อิงกับ renovate ฯลฯ แล้ว แต่ยังไม่ชัดเจนว่าช่วยแก้ปัญหาแบบนี้ได้หรือไม่
    เพราะยังเป็นทีมเล็ก การรับมือกับเครื่องมือที่มี ผลบวกลวง เยอะอย่าง snyk ก็เป็นภาระเหมือนกัน

    • แทนที่จะใช้ GitHub repository โดยตรง เราใช้แพ็กเกจสาธารณะจาก package repository ทั่วไปอย่าง NuGet, PyPI, npm และวาง Repository กับ Firewall ของ Sonatype เป็นพร็อกซีคั่นระหว่างเรากับ package repository
      Sonatype วิเคราะห์ทุกแพ็กเกจและใส่ metadata หลายอย่าง จากนั้นกำหนดนโยบายที่ใช้ใน Firewall เพื่อกรองส่วนที่เหลือออก
      ใช้ได้เฉพาะกับ dependency สาธารณะ แต่จากที่ใช้มาหลายปีถือว่าทำงานได้ค่อนข้างดี
      จนถึงตอนนี้ยังไม่เจอปัญหามัลแวร์ และแพ็กเกจที่มีช่องโหว่ที่รู้จักจะไม่สามารถเข้ามาใน codebase ได้ ถ้าของที่ใช้อยู่ถูกพบว่ามีช่องโหว่ก็จะได้รับการแจ้งเตือน
    • ที่ทำงานใช้ Semgrep Supply Chain และค่อนข้างพอใจ
      มันแบ่งช่องโหว่ supply chain ที่พบออกเป็น reachable, unreachable, และ unknown ทำให้คัดแยกได้ง่ายขึ้นมาก และลดเวลาที่ใช้ประเมินช่องโหว่ใหม่ได้มาก
    • ดูเหมือนใน subthread นี้จะสับสนระหว่างมัลแวร์กับช่องโหว่อยู่มาก
      ผู้ให้บริการที่ถูกพูดถึงไม่ได้ตรวจจับโค้ดอันตราย แต่ตรวจจับแค่ ช่องโหว่
      ต่อให้ตรวจจับช่องโหว่ได้ดี ก็ยังไม่ได้ปกป้องจากโค้ดอันตรายที่ถูกฝังไว้ใน codebase
    • กำลังสร้าง Packj ซึ่งเป็นเครื่องมือโอเพนซอร์สสำหรับตรวจจับแพ็กเกจ PyPI/NPM/Ruby/PHP/Maven/Rust ที่มีความเสี่ยง เช่น แพ็กเกจที่เปิดเผยว่าเป็นอันตราย แพ็กเกจที่ถูกทิ้งร้าง และแพ็กเกจ typosquatting
      มันทำการวิเคราะห์แบบ static, dynamic และ metadata และตรวจสอบคุณลักษณะมากกว่า 40 รายการ เช่น การเรียกใช้ shell, การใช้ SSH key, การสื่อสารผ่านเครือข่าย, การใช้ decode+eval เพื่อระบุแพ็กเกจที่เสี่ยง
      https://github.com/ossillate-inc/packj
    • Trivy ก็น่าลองดู
      จนถึงตอนนี้ทำงานได้ค่อนข้างดี
      https://trivy.dev/
  • อยากรู้ว่าธรรมเนียมการใช้ curl ดาวน์โหลดสคริปต์ติดตั้ง shell แล้วรันด้วย sudo จะสิ้นสุดลงเร็ว ๆ นี้ไหม
    วิธีแบบ “ถ้าต้องการติดตั้งซอฟต์แวร์ของเรา ให้รัน curl [https://somesite/install.sh](<https://somesite/install.sh>;)' | sudo sh” น่าจะเข้ากับโค้ดติดเชื้อที่กล่าวถึงในบทความได้เป็นอย่างดี

    • ในฐานะผู้เขียนงานวิจัยนี้ ยืนยันได้
      ระบบของเราระบุแพตเทิร์นที่กล่าวถึงได้ประมาณ 100 รายการทุกสัปดาห์ และในนั้นประมาณ 3% เป็นอันตราย
      อยากเห็นธรรมเนียมนี้หมดไป
    • น่าเสียดายที่ npm i ก็มีสิทธิ์แบบเดียวกัน
      ในบรรดาเครื่องมือดาวน์โหลด dependency ที่ใช้กันทั่วไปตอนนี้ เท่าที่รู้มีแค่ go get ที่ไม่รันโค้ดที่เป็นศัตรูในช่วงติดตั้งหรือ build
      อย่างน้อยเราต้องมีเครื่องมือที่ดีกว่านี้สำหรับทำงานใน sandbox เพื่อจำกัดความเสียหาย
      วิธีของ ChromeOS ที่ “virtual machine สามารถเปิดหน้าต่าง Wayland บนเดสก์ท็อปหลักได้” นั้นดูเรียบร้อยดี แต่ครั้งสุดท้ายที่ดู โค้ดส่วนนั้นไม่ได้สะอาดหรือเอาไปใช้ซ้ำได้เท่าไร
    • ตัวอย่างแบบนี้ควรใช้ example.com
      เป็นโดเมนที่สงวนไว้เพื่อจุดประสงค์นี้: https://www.rfc-editor.org/rfc/rfc2606.html#section-3
    • ก็ไม่ได้แย่ไปกว่าทางเลือกที่เป็นจริงอย่าง “เพิ่ม repository สำหรับดิสโทรแล้วเชื่อใจมัน”, “ดาวน์โหลด .deb/.rpm/ตัวติดตั้ง” หรือแย่ที่สุดคือ “เชื่อใจแพ็กเกจที่บุคคลที่สามแพ็กให้ ไม่ใช่ผู้เผยแพร่” เท่าไรนัก
  • ใน npm สามารถบรรเทา การรันมัลแวร์ ได้ด้วย --ignore-scripts
    https://blog.uirig.com/getting-rid-of-npm-scripts

    • แต่โค้ดอันตรายที่ดาวน์โหลดมาก็อาจถูกรันใน production แทน
      ถ้าโชคดี มันอาจแสดงพฤติกรรมผิดปกติใน CI จนถูกจับได้
      ทางแก้จริง ๆ คือ ระบบชื่อเสียง แบบ https://github.com/crev-dev/cargo-crev แต่น่าเสียดายที่แทบไม่มีคนใช้
    • จากมุมมองด้านความปลอดภัย ควรเป็นค่าเริ่มต้น
      คอมเมนต์ที่บอกว่าจำเป็นต้องมี Makefile ก็น่าสังเกตด้วย
  • เมื่อมีรายงานแบบนี้ออกมาเรื่อย ๆ ช่วงหลายเดือนที่ผ่านมาเลยค่อย ๆ ปรับปรุงความปลอดภัยของสภาพแวดล้อมการพัฒนา
    ใช้ VSCode dev containers ในการพัฒนา: https://code.visualstudio.com/docs/devcontainers/create-dev-...
    ถ้าสร้างไว้ครั้งหนึ่งแล้วก็ใช้งานง่ายแม้ไม่มีความรู้ Docker มากนัก และเหมาะกับการรันแอปเว็บ/คอนโซล แต่ของอย่าง Flutter หรือ Electron ยังทำได้ยาก
    สำหรับโปรเจกต์เล็ก ๆ ก็เริ่มคุ้นกับ GitHub Codespaces แล้ว: https://github.com/codespaces
    เคยมีครั้งหนึ่งตอนสัมภาษณ์ที่ต้องไลฟ์โค้ดดิ้งแก้โปรเจกต์ Node ง่าย ๆ ถ้าเป็นช่วงนี้เจอสถานการณ์แบบนั้นคงใช้คอนเทนเนอร์หรือ Codespaces แน่นอน: https://www.welivesecurity.com/en/eset-research/lazarus-luri...
    แนวทางปฏิบัติที่ดีของ npm, Node, Docker คืออ่านคำแนะนำ OWASP เป็นประจำ และสำหรับ Docker ก็นำมาใช้ในลักษณะเช่น ใช้ image ที่เล็กที่สุดเท่าที่ทำได้และระบุ image tag อย่างชัดเจน: https://cheatsheetseries.owasp.org/cheatsheets/NodeJS_Docker...
    สำหรับแพ็กเกจ npm/python ก่อนติดตั้งจะตรวจด้วย socket.dev เรื่องการเข้าถึง environment variable, การเรียกเครือข่าย, การโจมตี supply chain, การเปลี่ยนเจ้าของโค้ดล่าสุด ฯลฯ และตามที่ OWASP แนะนำ ก็สามารถปิดใช้งานสคริปต์ postinstall แบบ global ได้ด้วย: https://cheatsheetseries.owasp.org/cheatsheets/NPM_Security_...

  • มีกรณีที่ยังไม่ถึง 1 ปี เป็น repository ที่มีไวรัส โทรจัน: https://github.com/orgs/community/discussions/63603

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

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