สรุปย่อ
ในวันที่ 31 มีนาคม 2569 ผู้โจมตีได้บุกรุกบัญชี npm ของผู้ดูแลหลักของ Axios ซึ่งเป็นไคลเอนต์ HTTP JavaScript ที่ได้รับความนิยมสูงสุดด้วยยอดดาวน์โหลด 83 ล้านครั้งต่อสัปดาห์ พวกเขาเผยแพร่เวอร์ชันที่เป็นอันตราย (1.14.1 และ 0.30.4) ซึ่งมี RAT (Remote Access Trojan) ข้ามแพลตฟอร์มที่ขโมยข้อมูลประจำตัว คีย์ SSH และโทเค็นคลาวด์จากเครื่องของนักพัฒนา ลดระดับ Axios เป็นเวอร์ชัน 1.14.0 ทันที หมุนเวียนความลับทั้งหมด และสแกนหาร่องรอยการประนีประนอมในระบบของคุณ
บทนำ
Axios ประมวลผลคำขอ HTTP มากกว่าไลบรารี JavaScript อื่นๆ หากคุณเคยสร้างไคลเอนต์ API, ทดสอบปลายทาง หรือเชื่อมต่อส่วนหน้ากับส่วนหลังในช่วงห้าปีที่ผ่านมา คุณน่าจะเคยใช้มัน
ในวันที่ 31 มีนาคม 2569 เวลา 00:21 UTC ผู้ไม่ประสงค์ดีได้เผยแพร่ Axios เวอร์ชัน 1.14.1 ผ่านบัญชีผู้ดูแลที่ถูกยึดครอง แพ็กเกจดังกล่าวดูเหมือนกับเวอร์ชันที่ถูกต้อง ความแตกต่างนั้นเล็กน้อย: มีเพียง package.json เท่านั้นที่เปลี่ยนไปใน 86 ไฟล์ แต่ไฟล์เดียวนี้ได้ฉีดการพึ่งพาปลอมที่เรียกว่า plain-crypto-js ซึ่งติดตั้งโทรจันเข้าถึงระยะไกล (Remote Access Trojan) ไปยังทุกเครื่องที่รัน npm install
เวอร์ชันที่เป็นอันตรายยังคงใช้งานได้ประมาณสองถึงสามชั่วโมงก่อนที่ npm จะถอนออก สองถึงสามชั่วโมงท่ามกลางยอดดาวน์โหลด 83 ล้านครั้งต่อสัปดาห์
💡หากคุณกำลังสร้างหรือทดสอบ API การโจมตีนี้พุ่งเป้าไปที่ชุดเครื่องมือของคุณโดยตรง ไคลเอนต์ HTTP ในตัวของ Apidog ช่วยลดความจำเป็นในการใช้ไลบรารี HTTP ของบุคคลที่สามในขั้นตอนการทำงานการทดสอบ API ของคุณ ซึ่งช่วยขจัดช่องโหว่ในการโจมตีนี้ทั้งหมด ดาวน์โหลด Apidog ฟรีเพื่อทำตามขั้นตอนการตรวจสอบความปลอดภัยด้านล่างนี้
บทความนี้จะอธิบายวิธีการโจมตี การตรวจจับว่าระบบของคุณถูกบุกรุกหรือไม่ และสิ่งที่ทีม API ควรเปลี่ยนแปลงเกี่ยวกับการจัดการการพึ่งพาในอนาคต
การโจมตีซัพพลายเชนของ Axios คลี่คลายลงได้อย่างไร
ไทม์ไลน์
ผู้โจมตีดำเนินการนี้อย่างแม่นยำภายในกรอบเวลา 18 ชั่วโมง:
-
30 มีนาคม, 05:57 UTC: แพ็กเกจล่อที่สะอาด
plain-crypto-js@4.2.0ถูกเผยแพร่ไปยัง npm -
30 มีนาคม, 23:59 UTC: เวอร์ชันที่เป็นอันตราย
plain-crypto-js@4.2.1ถูกเผยแพร่ โดยเพิ่ม hookpostinstallที่มี dropper -
31 มีนาคม, 00:21 UTC:
axios@1.14.1ถูกเผยแพร่โดยใช้บัญชีjasonsaaymanที่ถูกบุกรุก -
31 มีนาคม, 01:00 UTC:
axios@0.30.4ตามมา 39 นาทีต่อมา - 31 มีนาคม, ~03:15 UTC: npm ถอนการเผยแพร่ Axios ทั้งสองเวอร์ชันหลังจากรายงานจากชุมชน
-
31 มีนาคม, 04:26 UTC: npm เผยแพร่ stub ตัวยึดความปลอดภัยสำหรับ
plain-crypto-jsเพื่อป้องกันการเผยแพร่ซ้ำ
บัญชีถูกบุกรุกได้อย่างไร
ผู้โจมตีได้เข้าควบคุมบัญชี npm jasonsaayman ซึ่งเป็นผู้ดูแลหลักของ Axios และเปลี่ยนอีเมลเป็น ifstap@proton.me หลักฐานสำคัญ:
- การเผยแพร่ Axios ที่ถูกต้องใช้ GitHub Actions กับ OIDC Trusted Publisher ของ npm เวอร์ชันที่เป็นอันตรายขาดการผูก OIDC
- ไม่มี
gitHeadในแพ็กเกจที่ถูกบุกรุก - ผู้โจมตีใช้โทเค็นการเข้าถึง npm ที่ถูกขโมยเพื่อเผยแพร่ด้วยตนเองแทนที่จะผ่าน CI/CD
องค์กรที่เผยแพร่แพ็กเกจ npm ควรตรวจสอบการขาด OIDC และ provenance แบบ CI/CD โดยอัตโนมัติ
เทคนิคการฉีดการพึ่งพา
ผู้โจมตีไม่ได้แก้ไขซอร์สโค้ดของ Axios แต่เปลี่ยนเพียงบรรทัดเดียวใน package.json เพื่อเพิ่ม plain-crypto-js@^4.2.1 เป็น dependency เวลาทำงาน แพ็กเกจนี้มีอยู่เพียงเพื่อกระตุ้น hook postinstall ระหว่าง npm install เท่านั้น
การวิเคราะห์ไบนารีพบว่ามีเพียง package.json ที่แตกต่างกันระหว่าง 1.14.0 และ 1.14.1
เพย์โหลดที่เป็นอันตรายทำอะไร
กลไก Dropper
hook postinstall ใน plain-crypto-js ดำเนินการไฟล์ setup.js ที่ถูกอำพรางด้วยสองชั้น:
- XOR cipher ("OrDeR_7077")
- Base64 + reverse string
หลังถอดรหัส dropper จะตรวจสอบแพลตฟอร์มและรันเพย์โหลดที่เหมาะสม
เส้นทางการโจมตีที่เฉพาะเจาะจงกับแพลตฟอร์ม
macOS:
เขียน AppleScript ไปยัง /tmp/6202033
ดำเนินการผ่าน osascript
ดาวน์โหลดเพย์โหลดไปยัง /Library/Caches/com.apple.act.mond
Windows:
คัดลอก PowerShell ไปยัง %PROGRAMDATA%\wt.exe
ดำเนินการ VBScript dropper ผ่าน cscript
Linux:
ดาวน์โหลด Python RAT ไปยัง /tmp/ld.py
ดำเนินการผ่าน nohup python3
แต่ละสายติดต่อ C2 server พร้อม POST body เฉพาะแพลตฟอร์ม:
- macOS:
packages.npm.org/product0 - Windows:
packages.npm.org/product1 - Linux:
packages.npm.org/product2
ความสามารถของ RAT
RAT ที่ติดตั้งรองรับ:
- รันคำสั่ง shell ตามสั่ง
- ขโมยไฟล์ระบบ
- แสดงรายการและฉีด process
- ฉีดไบนารีในหน่วยความจำ (fileless)
- สื่อสารกับ C2 ทุก 60 วินาที
ผู้โจมตีควบคุมเครื่องพัฒนาได้เต็มรูปแบบ สามารถขโมย .env, คีย์ API, SSH, โทเค็นคลาวด์ ฯลฯ
การป้องกันนิติเวช: เพย์โหลดที่ทำความสะอาดตัวเอง
Dropper จะ:
- ลบ
setup.js - ลบ
package.jsonที่เป็นอันตราย - เปลี่ยนชื่อ
package.md(4.2.0) เป็นpackage.json
npm list จะเห็นเป็น 4.2.0 แม้จริงๆ จะรัน 4.2.1 นักพัฒนาส่วนใหญ่จะไม่สังเกตเห็น
ใครอยู่เบื้องหลังการโจมตีนี้
Google Threat Intelligence Group ระบุว่าเป็น UNC1069 (เกาหลีเหนือ) โดยมัลแวร์มีความทับซ้อนกับ WAVESHAPER (backdoor C++ ที่ Mandiant ติดตาม)
กลุ่มนี้เชี่ยวชาญการโจมตีซัพพลายเชน โดยเน้นเครื่องมือ dev เพื่อขโมย credentials และโครงสร้างพื้นฐานคลาวด์
การโจมตีนี้มีความซับซ้อนสูง: การฉีด dependency, RAT ข้ามแพลตฟอร์ม, เทคนิคทำความสะอาด เป็นระดับปฏิบัติการข่าวกรอง
วิธีตรวจสอบว่าคุณได้รับผลกระทบหรือไม่
ขั้นตอนที่ 1: ตรวจสอบเวอร์ชัน Axios ของคุณ
รันในแต่ละโปรเจกต์:
npm list axios 2>/dev/null | grep -E "1\.14\.1|0\.30\.4"
หากมีผลลัพธ์ แสดงว่าใช้เวอร์ชันที่ถูกบุกรุก
ขั้นตอนที่ 2: ตรวจสอบการพึ่งพาที่เป็นอันตราย
ls node_modules/plain-crypto-js 2>/dev/null && echo "POTENTIALLY AFFECTED"
ถ้ามี directory นี้ แสดงว่าเพย์โหลดเคยถูกรัน
ขั้นตอนที่ 3: ตรวจสอบหาสิ่งตกค้างของ RAT ในระบบของคุณ
macOS:
ls -la /Library/Caches/com.apple.act.mond 2>/dev/null
Linux:
ls -la /tmp/ld.py 2>/dev/null
Windows (PowerShell):
Test-Path "$env:PROGRAMDATA\wt.exe"
ขั้นตอนที่ 4: ตรวจสอบตัวบ่งชี้เครือข่าย
บล็อกและสแกนการเชื่อมต่อไปยัง:
- โดเมน C2:
sfrclak.com - IP C2:
142.11.206.73 - URL C2:
http://sfrclak.com:8000/6202033
ขั้นตอนที่ 5: ตรวจสอบบันทึกการสร้าง CI/CD
ตรวจสอบ pipeline ที่รัน npm install/ci ระหว่าง 31 มี.ค. 00:21-03:15 UTC อาจมีการรัน dropper ในสภาพแวดล้อม build
ขั้นตอนการแก้ไขเบื้องต้นทันที
หากพบตัวบ่งชี้การบุกรุก ให้ดำเนินการดังนี้:
1. ลดระดับ Axios ทันที
npm install axios@1.14.0
# หรือสำหรับ 0.x
npm install axios@0.30.3
2. เพิ่มการแทนที่เวอร์ชันลงใน package.json ของคุณ
{
"overrides": {
"axios": "1.14.0"
}
}
สำหรับ Yarn:
{
"resolutions": {
"axios": "1.14.0"
}
}
3. ลบแพ็คเกจที่เป็นอันตราย
rm -rf node_modules/plain-crypto-js
4. หมุนเวียนข้อมูลประจำตัวทั้งหมด
เปลี่ยนทุก credentials ที่มีในเครื่อง เช่น:
- โทเค็น npm
- AWS/GCP/Azure credentials
- SSH keys
- GitHub tokens
- คีย์ API ใน
.env - Database credentials
- Secrets อื่นๆ
5. บล็อก C2 ที่ระดับเครือข่าย
echo "0.0.0.0 sfrclak.com" | sudo tee -a /etc/hosts
6. หากพบสิ่งตกค้าง ให้สร้างเครื่องใหม่
ถ้ามีไฟล์ตกค้าง RAT ให้รีเซ็ตเครื่องใหม่จาก image ที่ปลอดภัย
การป้องกันระยะยาวสำหรับทีมพัฒนา API
ใช้ lockfiles และปักหมุดเวอร์ชันที่แน่นอน
ระบุเวอร์ชันตรงใน package.json และคอมมิต lockfile
{
"dependencies": {
"axios": "1.14.0"
}
}
ใช้ npm ci แทน npm install ใน CI/CD
ปิดใช้งานสคริปต์ postinstall ใน CI/CD
npm ci --ignore-scripts
หรือใน .npmrc:
ignore-scripts=true
ตรวจสอบการพึ่งพาอย่างสม่ำเสมอ
npm audit
npx socket-security/cli audit
ใช้ใน pipeline เพื่อบล็อก build เมื่อพบ critical/high vulnerability
ลดพื้นผิวการพึ่งพาไคลเอนต์ HTTP ของคุณ
ใช้ไคลเอนต์ HTTP ในตัว เช่น Apidog แทนการใช้ Axios, node-fetch หรือ got
- ทดสอบ API: ใช้เครื่องมือสร้าง test ของ Apidog
- ดีบัก API: ใช้ request inspector ในตัว
- เซิร์ฟเวอร์จำลอง: ใช้ mock ของ Apidog
- CI/CD: ใช้ Apidog CLI โดยไม่ต้องพึ่ง HTTP npm
ลองใช้ Apidog ฟรี เพื่อลดความเสี่ยงซัพพลายเชน
ตรวจสอบที่มาของแพ็กเกจ
npm รองรับ provenance ผ่าน Sigstore:
npm audit signatures
หากมีเวอร์ชันใหม่แต่ไม่มี provenance/OIDC ให้ถือว่าน่าสงสัย
สิ่งนี้มีความหมายต่อระบบนิเวศ JavaScript อย่างไร
รูปแบบความไว้วางใจพังทลายลง
ความปลอดภัย npm ขึ้นกับบัญชีผู้ดูแล โทเค็นที่มีอายุยาวนานยังถูกขโมยได้
แนวคิดที่เสนอ:
- บังคับใช้ OIDC สำหรับแพ็คเกจสำคัญ
- การเผยแพร่โดยต้องมีผู้อนุมัติสองคน
- จำกัดขอบเขตสิทธิ์ของ postinstall script
การโจมตีซัพพลายเชนไม่ชะลอตัวลง
npm, PyPI, RubyGems ถูกโจมตีอย่างต่อเนื่อง คิดถึง dependency tree เป็น attack surface
การเปรียบเทียบ: แนวทางการพึ่งพาไคลเอนต์ HTTP
| แนวทาง | ความเสี่ยงซัพพลายเชน | ภาระในการบำรุงรักษา | ความสามารถในการทดสอบ |
|---|---|---|---|
| Axios + สคริปต์แบบกำหนดเอง | สูง (การพึ่งพาจากบุคคลที่สาม) | สูง (การจัดการเวอร์ชัน) | ต้องตั้งค่าด้วยตนเอง |
| Node.js native fetch | ต่ำ (สร้างขึ้นในรันไทม์) | ต่ำ | คุณสมบัติการทดสอบจำกัด |
| ไคลเอนต์ในตัวของ Apidog | ไม่มี (ไม่ขึ้นกับ npm) | ไม่มี (จัดการโดยแพลตฟอร์ม) | ทดสอบ, Mock, เอกสารเต็มรูปแบบ |
| สคริปต์ curl/httpie | ต่ำ (เครื่องมือระดับระบบ) | ปานกลาง | ระบบอัตโนมัติจำกัด |
คำถามที่พบบ่อย
ตอนนี้ Axios ปลอดภัยที่จะใช้งานแล้วหรือไม่?
ใช่ เวอร์ชัน 1.14.0 และ 0.30.3 สะอาดแล้ว ตรวจสอบเวอร์ชันที่ติดตั้งด้วย npm list axios และตรวจสอบ lockfile
ฉันจะรู้ได้อย่างไรว่า RAT ทำงานบนเครื่องของฉันหรือไม่?
ตรวจสอบไฟล์ตกค้าง: /Library/Caches/com.apple.act.mond (macOS), /tmp/ld.py (Linux), %PROGRAMDATA%\wt.exe (Windows) และดูว่ามี node_modules/plain-crypto-js หรือไม่ การไม่มีไฟล์ตกค้างไม่ได้การันตีความปลอดภัยหากเคยติดตั้งเวอร์ชันที่ถูกบุกรุก
ฉันควรเลิกใช้ Axios เลยหรือไม่?
ไม่จำเป็น Axios ยังเป็นไลบรารีที่ได้รับการดูแลอย่างดี แต่ควรพิจารณาว่าคุณต้องใช้ไคลเอนต์ HTTP ภายนอกหรือไม่ Node.js 18+ มี fetch ในตัว หรือใช้แพลตฟอร์มแบบ Apidog ที่มี HTTP client ในตัว
ฉันจะป้องกันการโจมตีซัพพลายเชนในโปรเจกต์ของฉันได้อย่างไร?
- ปักหมุดเวอร์ชันให้แน่นอน
- คอมมิต lockfile
- ใช้
npm ci --ignore-scriptsใน CI/CD - ตรวจสอบ dependency อย่างสม่ำเสมอ
- ตรวจสอบ provenance ของแพ็กเกจ
- ลดขนาด dependency tree
- พิจารณาย้าย workflow ทดสอบ API ไปยังแพลตฟอร์มที่ไม่อาศัย npm HTTP client
การโจมตีครั้งนี้เกี่ยวข้องกับกรณี Claude Code หรือไม่?
เกิดขึ้นวันเดียวกันแต่ไม่เกี่ยวข้องกัน Axios ถูกโจมตีซัพพลายเชน ส่วน Claude Code รั่วไหลจาก build tool
ใครอยู่เบื้องหลังการโจมตี Axios?
UNC1069 (เกาหลีเหนือ) โดยมีมัลแวร์ที่คล้าย WAVESHAPER
มีนักพัฒนาได้รับผลกระทบกี่ราย?
เวอร์ชันที่เป็นอันตรายเผยแพร่ 2-3 ชั่วโมง ขณะนี้ npm ยังไม่เผยแพร่ตัวเลขอย่างเป็นทางการ
Apidog สามารถช่วยป้องกันการโจมตีซัพพลายเชนได้หรือไม่?
Apidog ลดโอกาสโจมตีโดยจัดเตรียม HTTP client ในตัวสำหรับงาน API ทั้งหมด ไม่ต้องติดตั้งไลบรารี HTTP ผ่าน npm ซึ่งลดพื้นผิวการโจมตีจาก dependency
ประเด็นสำคัญ
- การโจมตี Axios ส่งผลยอดดาวน์โหลด 83 ล้านครั้ง/สัปดาห์ ผ่านบัญชีผู้ดูแลที่ถูกขโมยเพียงรายเดียว
- RAT กำหนดเป้าหมายทุกแพลตฟอร์มและขโมย credentials สำคัญ
- ตรวจสอบระบบของคุณทันทีด้วยขั้นตอนด้านบน
- ปักหมุดเวอร์ชัน dependency และปิดใช้งาน postinstall scripts ใน CI/CD
- ลดพื้นผิว dependency HTTP โดยใช้เครื่องมือในตัว เช่น Apidog
- ความปลอดภัย registry ของแพ็กเกจเป็นปัญหาสำคัญในทุก ecosystem
การโจมตี Axios คือสัญญาณเตือน ทุก dependency ใน node_modules คือเรื่องของความไว้วางใจ ควรตรวจสอบและตัดสินใจอย่างตั้งใจ ไม่ใช่โดยค่าเริ่มต้น
Top comments (0)