5 คะแนน โดย GN⁺ 2025-09-17 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เกิดการโจมตีแบบ supply chain ในระบบนิเวศ NPM โดยมีการฝัง มัลแวร์แบบแพร่กระจายตัวเอง ลงในแพ็กเกจมากกว่า 40 รายการ รวมถึง @ctrl/tinycolor ที่ได้รับความนิยม ทำให้ซีเคร็ตในสภาพแวดล้อมการพัฒนาและแม้แต่ข้อมูลรับรองของ CI/CD สามารถติดเชื้อแบบลูกโซ่ได้ โดยเวอร์ชันที่ติดเชื้อถูกลบออกจาก npm แล้ว
  • เพย์โหลดของการโจมตีจะรัน Webpack bundle (bundle.js, ~3.6MB) แบบอะซิงก์ระหว่างขั้นตอนติดตั้ง npm และทำ การเก็บรวบรวม credentials ในวงกว้าง ผ่านตัวแปรสภาพแวดล้อม ระบบไฟล์ และ cloud SDK
  • ลอจิกอันตรายใช้ NpmModule.updatePackage เพื่อบังคับแพตช์และเผยแพร่แพ็กเกจอื่น ทำให้เกิด การแพร่กระจายแบบต่อเนื่อง, และฉีดเวิร์กโฟลว์ shai-hulud เข้าไปใน GitHub Actions เพื่อขโมยซีเคร็ตขององค์กรด้วย toJSON(secrets)
  • ข้อมูลที่รวบรวมได้จะถูกส่งออกโดยการสร้าง ที่เก็บ GitHub แบบสาธารณะชื่อ ‘Shai-Hulud’ ทำให้ข้อมูลรั่วไหลภายใต้ภาพลักษณ์ของกิจกรรมการพัฒนาปกติ และมีความสามารถในการหลบเลี่ยงการตรวจจับสูง
  • มีการเข้าถึงโทเค็นและ metadata endpoint ของ AWS/GCP/Azure/NPM/GitHub รวมถึงการค้นหาซีเคร็ตโดยอาศัย TruffleHog อย่างแนบเนียน
  • จำเป็นต้องลบแพ็กเกจทันที ทำความสะอาดรีโพซิทอรี เปลี่ยนข้อมูลรับรองทั้งหมด พร้อมทั้ง ตรวจสอบ CloudTrail/GCP Audit logs, บล็อก webhook, และนำ branch protection/Secret Scanning/นโยบาย cooldown มาใช้

Affected Packages

  • มีรายงานว่าได้รับผลกระทบ รวม 195 แพ็กเกจ/เวอร์ชัน โดยตัวอย่างสำคัญได้แก่ @ctrl/tinycolor(4.1.1, 4.1.2), หลายแพ็กเกจในเนมสเปซ @ctrl/, กลุ่มโมดูล @crowdstrike/, ngx-bootstrap/ngx-toastr/ng2-file-upload/ngx-color ครอบคลุมทั้งระบบนิเวศ Angular/เว็บ UI, สแตกมือถือ @nativescript-community/ และ @nstudio/, ทูลเชนด้านชีววิทยาศาสตร์ของ teselagen/, รวมถึง ember-*, koa2-swagger-ui, pm2-gelf-json, wdio-web-reporter
  • สำหรับ เวอร์ชันที่แน่นอน ของแต่ละแพ็กเกจ ควรอ้างอิงตารางในต้นฉบับและ ตรวจสอบไขว้อย่างละเอียด ว่ามีการใช้งานเวอร์ชันดังกล่าวหรือไม่
    • ตัวอย่าง: @ctrl/ngx-emoji-mart 9.2.1, 9.2.2, @ctrl/qbittorrent 9.7.1, 9.7.2, ngx-bootstrap 18.1.4, 19.0.3–20.0.5, ng2-file-upload 7.0.2–9.0.1 เป็นต้น ซึ่งครอบคลุมในวงกว้าง

Immediate Actions Required

Identify and Remove Compromised Packages

  • ตรวจสอบว่ามีแพ็กเกจที่ติดเชื้อในโปรเจกต์หรือไม่: เช่นใช้ npm ls @ctrl/tinycolor เพื่อตรวจสอบ
  • ลบแพ็กเกจที่ติดเชื้อทันที: เช่นรัน npm uninstall @ctrl/tinycolor
  • ตรวจสอบร่องรอยในเครื่องจากการค้นหาแฮชของ bundle.js ที่ทราบแล้ว: ใช้ sha256sum | grep 46faab8a...

Clean Infected Repositories

  • ลบเวิร์กโฟลว์ GitHub Actions ที่เป็นอันตราย: ลบ .github/workflows/shai-hulud-workflow.yml
  • ตรวจหาและลบบรันช์ shai-hulud ที่ถูกสร้างบนรีโมต: ใช้ git ls-remote ... | grep shai-hulud แล้วตามด้วย git push origin --delete shai-hulud

Rotate All Credentials Immediately

  • จำเป็นต้อง เปลี่ยนข้อมูลรับรองทั้งหมด ได้แก่ NPM token, GitHub PAT/Actions secrets, SSH key, ข้อมูลรับรอง AWS/GCP/Azure, DB connection string, third-party token, CI/CD secrets เป็นต้น
  • ต้อง หมุนเวียนทั้งหมด รวมถึงรายการที่เก็บไว้ใน AWS Secrets Manager/GCP Secret Manager

Audit Cloud Infrastructure for Compromise

  • AWS: ตรวจสอบเวลาและรูปแบบของการเรียก BatchGetSecretValue, ListSecrets, GetSecretValue ใน CloudTrail และใช้ IAM Credential Report เพื่อตรวจหาการสร้างหรือใช้งานคีย์ที่ผิดปกติ
  • GCP: ตรวจสอบบันทึกการเข้าถึง Secret Manager ผ่าน Audit Logs และตรวจดูว่ามีเหตุการณ์ CreateServiceAccountKey หรือไม่

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

 
GN⁺ 2025-09-17
ความคิดเห็นใน Hacker News
  • ในฐานะคนที่ใช้แพ็กเกจที่โฮสต์บน npm รู้สึกว่ามันไม่ใช่วิธีที่ทำได้จริงในการเฝ้าดูทุก dependency รวมถึง dependency ของ dependency ทั้งหมดด้วยตัวเอง และเพราะไม่ได้เป็นผู้เชี่ยวชาญ TypeScript/JavaScript ก็คิดว่าคงตรวจพบมัลแวร์ที่ผู้โจมตีซ่อนไว้ได้ไม่ง่าย ช่วงนี้เลยกำลังกังวลเรื่องวิธีอัปเดตแบบ “โหมดหน่วงเวลา” คืออัปเดตเฉพาะเวอร์ชันที่ไม่ได้ใหม่ล่าสุด แต่เป็นเวอร์ชันที่ออกมานานพอสมควร โดยมองว่าถ้าแพ็กเกจถูกเปิดเผยสู่ภายนอกมาราว 6 สัปดาห์แล้ว โอกาสที่มัลแวร์จะถูกเปิดโปงก็น่าจะสูงขึ้น แต่มันก็ไม่ใช่วิธีที่สมบูรณ์แบบ และถ้าเป็นกรณีประเด็นด้านความปลอดภัยก็อยากให้มีเครื่องมือที่ตั้งข้อยกเว้นให้อัปเดตเป็นเวอร์ชันล่าสุดได้ทันที

    • มีฟีเจอร์ที่บทความพูดถึงตรง ๆ เลยคือ NPM Package Cooldown Check ถ้ามีการเพิ่มเวอร์ชันแพ็กเกจที่เพิ่งรีลีสภายในช่วงเวลาที่องค์กรตั้งไว้ (ค่าเริ่มต้น 2 วัน) เข้าไปใน pull request ระบบจะทำให้บิลด์ล้มเหลวอัตโนมัติ เนื่องจากการโจมตี supply chain ส่วนใหญ่ถูกตรวจพบภายใน 24 ชั่วโมง แค่รอช่วงสั้น ๆ ก็ช่วยลดความเสี่ยงด้านความปลอดภัยได้มาก

    • เพราะการตรวจสอบ dependency ทั้งหมดทำได้ยาก เลยอยากเสนอว่าควรลดจำนวน dependency ให้มากที่สุด และใช้เฉพาะแพ็กเกจที่เป็นที่รู้จักและน่าเชื่อถือ เท่าที่จะทำได้ ถ้าไม่ได้อยู่ในสภาพแวดล้อมที่ควบคุมได้จนเชื่อใจผู้เขียนทุกคนได้ การรักษาแนวคิด 'not-invented-here' ไว้ในระดับหนึ่งก็ดูเป็นทางเลือกที่สมเหตุสมผล

    • ปกติมีนิสัย pin เวอร์ชันไว้ชัดเจนใน package.json และใช้ npm ci เพื่อให้ติดตั้งเฉพาะเวอร์ชันที่ระบุใน package-lock.json ใน CI ก็รัน npm audit เพื่อรับการแจ้งเตือนถ้ามีช่องโหว่ในแพ็กเกจ แบบนี้แพ็กเกจจะอยู่ในสภาพแทบจะ “แช่แข็ง” และอายุของแพ็กเกจเองก็ช่วยลดโอกาสการติดเชื้อได้ด้วย

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

    • ใน Python ก็จำกัดการอัปเดตในลักษณะคล้ายกันได้ด้วย uv เช่นใช้คำสั่ง uv lock --exclude-newer $(date --iso -d "2 days ago") เพื่อยกเว้นเวอร์ชันที่รีลีสภายใน 2 วันที่ผ่านมา

  • ปัญหาแบบนี้เกิดขึ้นเพราะแพ็กเกจหรือเวอร์ชันใหม่ ๆ ไม่ได้ถูกเฝ้าระวัง ทางที่ดีที่สุดคือแยกการใช้งานแบบ Debian ออกเป็นดิสทริบิวชันเสถียรที่รับเฉพาะ security patch กับ bugfix และดิสทริบิวชัน testing/unstable ที่ package maintainer คอยเฝ้าดู ทุกคนที่ทำงานกับคลังแพ็กเกจโอเพนแบบรวมศูนย์ (NPM, Python, Rust ฯลฯ) ล้วนเจอปัญหาเดียวกัน

    • ปัญหาอยู่ที่วัฒนธรรมของนักพัฒนา การมี dependency (รวมถึง transitive dependency) เป็นร้อย ๆ ตัวแล้วปล่อยให้อัปเดตอัตโนมัติโดยไม่คิดอะไร คือปัญหาในตัวมันเอง การเลือกเปิดให้สภาพแวดล้อม build/run ของตัวเองรับโค้ดจากบุคคลที่สามมหาศาลขนาดนั้น ย่อมต้องมาพร้อมความรับผิดชอบ

    • ฝั่งดิสทริบิวชันเองก็ยิ่งรู้สึกหนักกับจำนวนแพ็กเกจที่ต้องดูแลมากขึ้นเรื่อย ๆ จริง ๆ แล้วนี่ก็เป็นเหตุผลที่ ecosystem รายภาษา (เช่น CPAN, Maven, RubyGems ฯลฯ) เติบโตขึ้นมา เพราะลินุกซ์ดิสทริบิวชันอย่างเดียวให้แอปที่ผู้ใช้ต้องการได้ไม่พอ จึงเกิดช่องทางอย่าง freshmeat, linuxbrew, flatpak, PPA และอื่น ๆ ขึ้นมา ไม่คิดว่าชุมชนไหนจะมีศักยภาพมากพอจะเฝ้าดูและซัพพอร์ตหลายสาขาของไลบรารีจำนวนมหาศาลได้ทั้งหมด

    • ในฐานะ Debian developer รู้สึกว่าก่อนจะรวม upstream code เข้าไป ตอนนี้มี “noise” เพิ่มขึ้นเรื่อย ๆ มากจนยากมากที่จะมองเห็นการเปลี่ยนแปลงจริง โดยเฉพาะการเปลี่ยนสไตล์เล็ก ๆ น้อย ๆ หรือการอัปเดต tooling อยากให้หลีกเลี่ยงการเปลี่ยนแบบนี้ เว้นแต่จะเป็น refactoring, bug fix, การเพิ่มฟีเจอร์ หรือผลจาก tooling ที่ช่วยค้นหาโค้ดมีปัญหา ซึ่งเป็นสิ่งที่ต้องให้คนตรวจจริง ๆ

    • ใน Rust มีระบบชื่อ cargo vet ที่บริษัทอย่าง Google และ Mozilla เข้าร่วมเพื่อแชร์และตรวจสอบแพ็กเกจร่วมกันแบบอัตโนมัติ

    • คิดว่าน่าจะมีวิธีคงความกระจายศูนย์ไว้ พร้อมมีราวกันตกด้านความปลอดภัยได้ เช่น แพ็กเกจที่มีขนาดใหญ่พอควรอาจบังคับให้ต้องได้รับอนุมัติจาก 2 บัญชีที่เปิดใช้ 2FA หรือแพ็กเกจยอดนิยมอาจให้อัปโหลดขึ้น npm ได้เฉพาะผ่านระบบ reproducible build เท่านั้น แบบนี้ไม่จำเป็นต้องทิ้งความกระจายศูนย์ทั้งหมด แค่เพิ่มความยุ่งยากอีกนิดสำหรับโปรเจกต์ขนาดใหญ่

  • การโจมตี supply chain ที่เกิดขึ้นต่อเนื่องช่วงหลังทำให้ผมเริ่มคิดเรื่อง server rendering อย่างจริงจังมากขึ้น (โดยไม่ใช้ JavaScript) พอมี HTMX ก็รู้สึกว่าจริง ๆ แล้วไปได้ไกลมากโดยไม่ต้องใช้ JavaScript และแอปก็น่าจะเร็วและเสถียรกว่าด้วย

    • อยากเน้นว่าสภาพแวดล้อม JS แบบดั้งเดิมจริง ๆ แล้วคือ sandbox ที่ปลอดภัยที่สุด ตลอดเกือบ 30 ปีที่ผ่านมา มีการรันโค้ด JS ที่ไม่น่าเชื่อถือบนอุปกรณ์นับพันล้านเครื่อง แต่กรณีโจมตีวงกว้างที่สำเร็จผ่าน browser engine มีน้อยมาก อย่างไรก็ตาม สภาพแวดล้อม NodeJS และ npm นั้นอยู่ในสภาพที่ต้องออกแบบใหม่ด้านความปลอดภัยทั้งระบบ เรื่องอย่าง leftpad ก็มีต้นตอมาจากวัฒนธรรมที่เอาแม้แต่โค้ด snippet ง่าย ๆ ไปลง npm

    • รู้สึกแปลกที่การโจมตีแบบนี้มักถูกลดทอนให้กลายเป็นปัญหาเฉพาะของบางสภาพแวดล้อม (JavaScript) โดยอัตโนมัติ ทั้งที่จริงแม้แต่ npm เองยังมีมาตรการเสริมความปลอดภัยบางอย่างที่สภาพแวดล้อมอื่น (PyPI, Crates ฯลฯ) ยังไม่มีเลย ซึ่งดูเป็นปัญหาใหญ่กว่า

    • การ vendor โค้ดอาจช่วยลดความเสี่ยงได้ แต่ไม่ใช่คำตอบของปัญหาระดับรากฐาน ถ้า NPM จริงจังกับความปลอดภัย ก็ควรบังคับใช้ 2FA ในการ publish และสแกนแพ็กเกจล่วงหน้า รวมถึงบังคับให้มีการเซ็นด้วย hardware key ด้วย semver หรือ CRC อย่างเดียวไม่พอ และทั้งหมดนี้ควรถูกติดตั้งมาเป็นค่าเริ่มต้นในระบบจัดการแพ็กเกจเลย

    • จริง ๆ แล้วการโจมตีแบบนี้ไม่ใช่ปัญหาเฉพาะของ JavaScript แต่เกิดจากการที่นักพัฒนาไม่ได้ตรวจสอบมากพอเวลาเพิ่ม dependency ใหม่ ซึ่งใช้ได้เหมือนกันกับ ecosystem ของภาษาอื่นอย่าง Rust หรือ Go

    • ทุกภาษาที่พึ่งพา package manager มากและมี standard library บาง ต่างก็เปราะบางเหมือนกัน ในระยะยาวเลยคิดว่าน่าจะกลับไปใช้ vanilla JavaScript มากขึ้น Rust ก็มีการพึ่งพาแพ็กเกจสูงเหมือนกัน ตรงกันข้าม Go ดูเป็นตัวอย่างที่ดีในเรื่องนี้

  • คิดว่าเราต้องมีระบบที่ติดตามโค้ดขนาดเล็กที่ทำหน้าที่ติดตั้งและตรวจสอบได้ พร้อมทั้งเซ็น commit/release ด้วยกุญแจที่เชื่อถือได้และตรวจสอบยืนยันได้ ตอนนี้มีแนวทาง npm provenance ที่ใช้ sigstore อยู่แล้ว แต่ดูเหมือนว่ายังไม่ถูกใช้อย่างแพร่หลาย และยังจำกัดอยู่แค่ระดับการยืนยันผู้เผยแพร่เป็นหลัก

  • ตั้งแต่ปี 2016 ก็มีการ รายงานช่องโหว่นี้ต่อ NPM แล้ว (คำแนะนำจาก CERT) แต่คำตอบของ NPM คือ WAI (working as intended)

    • เผื่อใครไม่รู้ว่า WAI คืออะไร: ปกติเป็นตัวย่อของ “working as intended”

    • ต่อให้ไม่มี postinstall script เลย ก็ดูเหมือนว่าในขั้นตอน build, การสตาร์ตเซิร์ฟเวอร์, การทดสอบ ฯลฯ ถ้ามีการ import โมดูลเมื่อไร มัลแวร์ก็น่าจะถูกรันอยู่ดี สุดท้ายหลัง npm install แล้วก็ต้องมีสักช่วงที่มีการรันอะไรจริง ๆ อยู่แล้ว...

  • ทำให้นึกถึงคอมเมนต์ที่เคยเห็นที่นี่ตอนเหตุการณ์ left-pad มีการพูดถึง maintainer npm ชื่อดังคนหนึ่งที่มี npm package 600 ตัวและโค้ด JavaScript 1,200 บรรทัด เคสที่อยากยกเป็นตัวอย่างคือ esbuild ซึ่งแทบไม่มี dependency ภายนอกและใช้แค่ Go standard library
    โปรเจกต์อื่นที่ถูกเรียกว่า “next-gen” ถ้าดู dependency chain ก็มีไม่มากเหมือนกัน เช่น biomejs, swc แต่ถ้าดู Rust ต้นฉบับจริง ๆ แล้ว biomejs, swc ก็ยังมี dependency จำนวนมาก คาดว่าถ้าโปรเจกต์แบบนี้แพร่หลาย ecosystem ของ cargo ก็คงเดินตามรอยเดิม ถ้าใครรู้จักโปรเจกต์ใหญ่ที่เขียนด้วยแนวเข้มงวดแบบ esbuild ก็อยากให้แนะนำ

    • หนึ่งในเหตุผลที่ย้ายไป Go คือกระแสไลบรารีแบบ purego ซึ่งมักพึ่งพาแค่ standard library กับ golang.org/x และคอมไพล์ได้โดยไม่ต้องใช้ CGO ทำให้พกพาได้ดี go mod vendor ช่วยบริหารความเสี่ยงระยะสั้นได้ แต่ไม่ใช่คำตอบระยะยาว Go เองก็ยังไม่มีการตรวจสอบแพ็กเกจแบบ end-to-end (เช่น การเซ็น/ตรวจคีย์) จึงยังมีช่องโหว่อยู่ โดยเฉพาะตอนนี้จุดสนใจไปอยู่ที่โครงสร้าง CI/CD มาก แต่ถ้าสามารถ build และ deploy ได้โดยไม่ต้องส่งต่อ signing key ก็น่าจะเพิ่มความปลอดภัยได้ ระบบจัดการแพ็กเกจน่าจะสนับสนุนลายเซ็น GPG และการเซ็น git commit แล้วค่อยนำไปใช้ในการเผยแพร่

    • กรณีของ eslint เป็นตัวอย่างที่น่าอึดอัดมาก ถ้าดู dependency graph จะเห็นว่ามหาศาล และถ้าผู้ดูแลไม่ให้ความสำคัญกับการลด dependency สุดท้ายก็เหลือแค่เปลี่ยนไปใช้ทางเลือกอื่น (oxlint)

    • ทางออกคือฟีเจอร์ที่ทำได้ง่าย ๆ ให้เขียนเองเพื่อลด dependency ภายนอก ปกติแค่นี้ก็ตัด dependency รวมได้ราว 2/3 แล้ว โดยเฉพาะอะไรที่ง่ายแบบ left-pad ก็ควรทำเองและเก็บไว้ในมือด้วยยูนิตเล็ก ๆ พร้อมการทดสอบ ภาระในการดูแลไม่ได้สูงขนาดนั้น dependency ที่ไม่จำเป็นควรถูกตัดทิ้งอย่างเด็ดขาด

    • สิ่งที่เห็นใน root Cargo.toml ของโปรเจกต์ Rust เป็นของทั้ง workspace และ dependency จริงของแต่ละ crate จะตื้นกว่านั้นมาก ต้องขุดลึกลงไปอีกถึงจะเห็นโครงสร้าง dependency จริง

    • ข้อเสียคือถ้าจะตรวจโปรเจกต์ JavaScript ตอนนี้ก็ต้องอ่าน Golang ได้ด้วย แถมยังมี post-install ที่ไปเรียก node install.js อีก สุดท้ายก็มีแค่ทางเลือกว่าจะเชื่อทั้งหมดหรืออ่านโค้ดเองทั้งหมด

  • ยังไม่อยากเชื่อว่า npm ยังรัน postinstall script ของทุก dependency เป็นค่าเริ่มต้นอยู่เลย Pnpm หรือ Bun จะรันเฉพาะกรณีที่อยู่ใน allowlist เท่านั้น ส่วน Composer ไม่รัน lifecycle script ของ dependency เลย คิดว่าวิธีพวกนี้ปลอดภัยกว่าเพราะ dependency package ในสภาพแวดล้อม build หรือ development มีความเสี่ยงจริง

    • สงสัยว่าทำไมการโจมตีใหญ่ ๆ แบบนี้ถึงไม่ค่อยได้ยินใน package manager อื่น (เช่น Rust build.rs, Python, Java ฯลฯ) ทั้งที่ไม่ใช่แค่ postinstall แต่แทบทุก ecosystem ก็ทำได้ในทางหลักการเหมือนกัน ดูเหมือนเหตุการณ์จะไปกระจุกอยู่ที่ npm เป็นหลัก

    • เห็นแล้วว่า ค่าเริ่มต้นของ Pnpm เปลี่ยนเป็นบล็อกสคริปต์ เลยอยากรู้ปฏิกิริยาของชุมชน (ทั้งเรื่องประสบการณ์ใช้งานจากการอนุญาตสคริปต์ และการใช้คำสั่ง allow แบบพร่ำเพรื่อ) และในชุมชน Python packaging ก็มีการถกคล้ายกันเกี่ยวกับ wheel variants อยู่ด้วย อยากอ้างอิงประสบการณ์จาก ecosystem อื่น

  • การโจมตีครั้งนี้แพร่ไปถึงมากกว่า 180 แพ็กเกจแล้ว ดู บล็อกของ Aikido Security

  • สงสัยว่าใครเป็นคนแรกที่พบการโจมตีนี้ แต่ละบล็อกให้เครดิตกันไม่เหมือนกันจนน่าสนใจ Aikido บอกว่า “เราเป็นคนค้นพบการโจมตีขนาดใหญ่” ส่วน Socket, Ox, Safety, Phoenix, Semgrep ฯลฯ ก็อธิบายกันไปคนละแบบ

    • ผมคือ Mackenzie ที่ทำงานอยู่ Aikido คนที่รายงานเรื่องนี้เป็นคนแรกคือ Daniel Pereira ซึ่งเป็นนักพัฒนา เขาส่งเรื่องต่อให้ Socket และ Socket ก็เป็นคนแรกที่วิเคราะห์ 40 แพ็กเกจแรกกับตัวมัลแวร์ จากนั้น Aikido พบเพิ่มอีก 147 แพ็กเกจและแพ็กเกจของ Crowdstrike ส่วน Step เป็นเจ้าแรกที่ระบุได้ว่ามัลแวร์นี้เป็นเวิร์มที่แพร่กระจายตัวเองได้ สิ่งที่น่าสนใจคือหลายองค์กรต่างก็มีบทบาทต่างกันอย่างอิสระ

    • ดูเหมือนว่านักพัฒนาหลายคนจะตรวจพบในเวลาใกล้เคียงกันมาก และ Step กับ Socket ก็อ้างถึงคนละคน สุดท้ายแล้วดูเหมือนว่าผู้ขายเครื่องมือความปลอดภัยในอุตสาหกรรมต่างก็จับได้ด้วยวิธีของตัวเอง ไม่ว่าจะเป็นการวิเคราะห์โค้ดด้วย AI (Socket, Aikido) หรือการมอนิเตอร์ pipeline ด้วย eBPF (Step)

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

    • บทความต้นฉบับอ้างข้อความตรง ๆ ว่า “@franky47 พบพฤติกรรมนี้และได้แจ้งเตือนชุมชนทันทีผ่าน GitHub issue

  • คิดว่าชื่อที่ผู้โจมตีตั้งว่า 'Shai Hulud' ค่อนข้างมีไหวพริบ เอาชื่อหนอนยักษ์มาตั้งให้มัลแวร์แบบเวิร์มจริง ๆ แถม bundle.js หลักก็ใหญ่ถึง 3.6MB แม้แต่มัลแวร์กลายพันธุ์ก็ยังตัวโตแบบสไตล์ npm

    • มีลางว่าคงอีกไม่นานสักการโจมตี supply chain ครั้งหนึ่งจะไปดึงอีกการโจมตี supply chain เข้ามาโดยบังเอิญ

    • มัลแวร์เองก็เดินตามกฎของมัวร์เหมือนกัน ปี 1991 tequila virus มีขนาด 2.6KB แต่ตอนนี้กลายเป็นระดับหลาย MB แล้ว