DEV Community

Cover image for วิธีรักษาความปลอดภัย NPM Dependencies คู่มือความปลอดภัยซัพพลายเชนสำหรับนักพัฒนา API
Thanawat Wongchai
Thanawat Wongchai

Posted on • Originally published at apidog.com

วิธีรักษาความปลอดภัย NPM Dependencies คู่มือความปลอดภัยซัพพลายเชนสำหรับนักพัฒนา API

TL;DR

การโจมตีซัพพลายเชน NPM พุ่งสูงขึ้นเกิน 3,000 แพ็คเกจที่เป็นอันตรายในปี 2024 เพียงปีเดียว และเหตุการณ์ compromise Axios เดือนมีนาคม 2026 แสดงให้เห็นว่าแม้แต่แพ็คเกจท็อป 10 ก็ยังไม่ปลอดภัย คู่มือนี้สรุปแนวทางปฏิบัติป้องกันที่นักพัฒนา API ต้องทำ: ตั้งแต่การบังคับใช้ lockfile, บล็อก postinstall script, ตรวจสอบ provenance, ใช้เครื่องมือวิเคราะห์พฤติกรรม ไปจนถึงการลดพื้นผิวการโจมตีของคุณ

ลองใช้ Apidog วันนี้

บทนำ

การโจมตีซัพพลายเชน Axios (31 มี.ค. 2026) ไม่ใช่ครั้งแรก และจะไม่ใช่ครั้งสุดท้าย แต่ความรุนแรงของมัน (ดาวน์โหลด 83 ล้านครั้ง/สัปดาห์, RAT ข้ามแพลตฟอร์ม, ใช้บัญชี maintainer ที่ถูกขโมย) ทำให้ต้องทบทวนแนวทางป้องกัน npm แบบเดิมๆ

สิ่งที่ต่างจากแนวคิด "อัปเดต dependencies" คือ การโจมตี Axios หลบเลี่ยงการป้องกันคลาสสิกทุกทาง: โค้ดอันตรายถูก inject ผ่าน dependency ผีที่ฝัง postinstall script, lockfile ไม่ช่วยถ้าคุณติดตั้งในจังหวะโจมตี, pin version ไม่ช่วยถ้ายังไม่ pin

นักพัฒนา API เสี่ยงสูง: test script, CI/CD pipeline, mock server, HTTP client ทั้งหมดดึง npm package ใด package หนึ่งที่โดน compromise อาจทำให้ API key, DB credentials, cloud token รั่วจาก dev machine ของคุณ

💡 Apidog ช่วยลดเวกเตอร์โจมตีสำคัญด้วย HTTP client ในตัวสำหรับทดสอบ API ไม่ต้องใช้ Axios, node-fetch หรือ got ใน test stack ดาวน์โหลด Apidog ฟรีเพื่อลดพื้นผิว npm dependency ขณะปฏิบัติตามกลยุทธ์ต่อไปนี้

คู่มือนี้จะอธิบายการป้องกัน 7 ชั้น ตั้งแต่ lockfile hygiene ถึง behavioral analysis


Layer 1: การบังคับใช้ lockfile

ทำไม lockfile ถึงสำคัญ

lockfile จะล็อกเวอร์ชันที่แน่นอนของทุก package และ transitive dependency ขณะติดตั้ง หากไม่มี lockfile, npm install จะ resolve เป็นเวอร์ชันล่าสุดที่ตรงกับ semver range เช่น ถ้า package.json มี "axios": "^1.14.0" แล้วมี 1.14.1 อันตราย คุณจะได้ตัวอันตราย

กฎพื้นฐาน

  • commit lockfile เสมอ ไม่ว่าจะเป็น package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lock ห้าม gitignore เด็ดขาด
  • ใช้การติดตั้งแบบ frozen ใน CI/CD ห้ามรัน npm install ปกติใน automation ใช้ frozen lockfile:
  # npm
  npm ci

  # yarn
  yarn install --frozen-lockfile

  # pnpm
  pnpm install --frozen-lockfile

  # bun
  bun install --frozen-lockfile
Enter fullscreen mode Exit fullscreen mode

npm ci จะลบ node_modules และติดตั้งจาก lockfile อย่างเข้มงวด ถ้า file ไม่ตรงจะ error ทันที

  • ตรวจ diff lockfile ใน PR เมื่อ PR เปลี่ยน lockfile ตรวจสอบเสมอ: dependency ใหม่, upgrade, registry URL อาจมีพิรุธ ใช้เครื่องมือเช่น Socket.dev แจ้งเตือน PR ที่ lockfile แปลก

ช่องว่างของ lockfile

lockfile ป้องกันการเปลี่ยนเวอร์ชันแบบไม่ตั้งใจ แต่ไม่กันตอนติดตั้งครั้งแรก ถ้า init project หรือเพิ่ม dependency ตอนช่วงเวลาโจมตี lockfile จะ lock เวอร์ชันอันตรายไว้ (จึงเป็นแค่ Layer 1)


Layer 2: ปิดใช้งาน postinstall script

เวกเตอร์โจมตีหลัก

ทั้ง Axios, ua-parser-js, event-stream ล้วนใช้ postinstall script inject โค้ดอันตรายระหว่าง npm install (ก่อนแอปคุณรัน, ก่อนตรวจสอบ package, ก่อน security tool runtime ใดๆ)

บล็อก script ทั่วโลก

เพิ่มใน .npmrc:

ignore-scripts=true
Enter fullscreen mode Exit fullscreen mode

หรือทาง CLI:

npm config set ignore-scripts true
Enter fullscreen mode Exit fullscreen mode

บล็อก lifecycle script (preinstall, install, postinstall, prepare) ทุกตัว

จัดการ package ที่ต้องใช้ script

บาง package (เช่น bcrypt, sharp, sqlite3) ต้องใช้ postinstall script

ทางเลือก 1: ติดตั้งแบบ ignore-scripts แล้ว rebuild package ที่ต้องใช้

npm ci --ignore-scripts
npm rebuild bcrypt sharp
Enter fullscreen mode Exit fullscreen mode

ทางเลือก 2: ใช้ allowlist (npm 10+)
สร้าง .scriptsrc.json:

{
  "allowScripts": {
    "bcrypt": true,
    "sharp": true
  }
}
Enter fullscreen mode Exit fullscreen mode

ทางเลือก 3: ใช้ prebuilt binaries

หลาย package สมัยนี้มี binary ที่ build ไว้อยู่แล้ว (เช่น sharp), ไม่ต้อง run postinstall script

คำเตือน PackageGate

ม.ค. 2026 พบ zero-day "PackageGate" ใน npm, pnpm, vlt, Bun: git-based dependency บางกรณีรันโค้ดได้แม้ปิด ignore-scripts ถ้าอ้าง git URL ต้อง pin commit hash และตรวจสอบ repo ด้วย


Layer 3: Pin exact version

เลิกใช้ semver range

npm install --save ใส่ caret เป็น default:

{ "axios": "^1.14.0" }
Enter fullscreen mode Exit fullscreen mode

เครื่องหมาย ^ หมายถึง "compatible with 1.14.0" ถ้ามี 1.14.1 อันตรายจะได้ตัวอันตราย

Pin เวอร์ชัน exact:

{ "axios": "1.14.0" }
Enter fullscreen mode Exit fullscreen mode

ตั้ง npm ให้ save exact:

# .npmrc
save-exact=true
save-prefix=''
Enter fullscreen mode Exit fullscreen mode

ใช้ overrides/ resolutions/ pnpm-overrides

ถ้า dependency คุณมี dependency ซ้อน ใช้ overrides คุมเวอร์ชัน:

{
  "overrides": {
    "axios": "1.14.0",
    "plain-crypto-js": "npm:empty-npm-package@1.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Yarn:

{
  "resolutions": {
    "axios": "1.14.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

pnpm:

{
  "pnpm": {
    "overrides": {
      "axios": "1.14.0"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

ข้อแลกเปลี่ยน

Pin exact version = ไม่ได้อัปเดต patch อัตโนมัติ ต้องอัปเดตเอง แต่แลกความปลอดภัยและควบคุม dependency ได้เต็มที่


Layer 4: ตรวจสอบที่มาของแพ็คเกจ (provenance)

ที่มาคืออะไร

Provenance ของ npm เชื่อมโยง package ที่ publish กับ source code และ build environment โดยใช้ Sigstore signature ใน transparency log สาธารณะ

หลักฐาน:

  • build จาก repo อะไร
  • CI/CD ตัวไหน
  • commit อะไรเป็น trigger

วิธีตรวจสอบ provenance

npm audit signatures
Enter fullscreen mode Exit fullscreen mode

จะแจ้งว่าติดตั้ง package ที่มี provenance ที่ถูกต้องหรือไม่

เวอร์ชัน Axios อันตรายไม่มี OIDC provenance ไม่มี commit จาก GitHub

เปิดใช้งาน provenance สำหรับแพ็คเกจของคุณ

ถ้าคุณ publish npm package ให้เพิ่มใน workflow:

# GitHub Actions
- uses: actions/setup-node@v4
  with:
    node-version: 20
    registry-url: https://registry.npmjs.org
- run: npm publish --provenance
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

และใน .npmrc:

provenance=true
Enter fullscreen mode Exit fullscreen mode

ข้อจำกัด

Provenance ยังเป็น opt-in, package ส่วนใหญ่ยังไม่มี และพิสูจน์ได้แค่ "build ที่ไหน" ไม่ได้พิสูจน์ว่า source code ปลอดภัย


Layer 5: ใช้เครื่องมือวิเคราะห์พฤติกรรม

เหนือกว่าการสแกน CVE

npm audit กับ Snyk ใช้ CVE database, ไม่เห็น zero-day หรือ malicious behavior ที่ยังไม่มีคนรายงาน

Socket.dev

Socket วิเคราะห์พฤติกรรม package ระหว่าง install/running แจ้งเตือน:

  • network request ตอน install
  • เข้าถึงไฟล์นอกไดเรกทอรี
  • shell command execution
  • harvest env variable
  • obfuscated code

PR ใหม่ที่เพิ่ม dependency แปลกจะโดน comment เตือน

ติดตั้ง Socket CLI และสแกนโปรเจกต์:

npm install -g @socketsecurity/cli
socket scan
Enter fullscreen mode Exit fullscreen mode

Snyk

Snyk จัดการ CVE พร้อม risk score, exploitability, remediation guide เหมาะกับ vulnerability ที่รู้จัก

npm install -g snyk
snyk test
Enter fullscreen mode Exit fullscreen mode

ควรใช้แบบ multi-layer

ใช้ทั้งสาม:

npm audit      # พื้นฐาน
socket scan    # วิเคราะห์พฤติกรรม
snyk test      # ช่องโหว่ที่รู้จัก
Enter fullscreen mode Exit fullscreen mode

รันทุกตัวใน CI/CD ถ้ามี flag แปลกควร block build


Layer 6: ลดพื้นผิว dependency

ถามตัวเองกับทุก dependency

แต่ละ package ใน node_modules คือการตัดสินใจ trust

Node.js project ทั่วไปมี hundreds transitive dependency

โจมตีได้ทุกตัวที่ถูก compromise

ถ้า dependency น้อยลง ความเสี่ยงลดลง

ตรวจ dependency tree

npm ls --all | wc -l                # ดูจำนวนทั้งหมด
npm ls --all | sort | uniq -c | sort -rn | head -20   # ดู package ซ้ำ
Enter fullscreen mode Exit fullscreen mode

ถามตัวเอง:

  • Node.js มี built-in แทนได้ไหม? (Node 18+ มี fetch, crypto, URL, FormData, ฯลฯ)
  • dependency นี้ ดึง transitive เยอะไหม?
  • เล็กพอจะ copy source code มา embed เองรึเปล่า?

ตัวอย่าง Native Replacement

แพ็คเกจ ทางเลือกเนทีฟ มีใน Node เวอร์ชั่น
axios, node-fetch, got fetch (global) Node.js 18
uuid crypto.randomUUID() Node.js 19
dotenv --env-file flag Node.js 20.6
chalk util.styleText() Node.js 21.7
glob fs.glob() Node.js 22
path-to-regexp Native URL pattern API Node.js 23

สำหรับ API testing โดยเฉพาะ

โดยปกติคุณต้องใช้ HTTP client, assertion, test runner, mock server ทุกตัวคือ dependency

Apidog แทนที่ทั้งหมดนี้:

  • HTTP client: ในตัว, ไม่ต้องใช้ npm
  • Assertion: visual test builder + built-in assertion
  • Test runner: scenario automation + CI/CD integration ผ่าน Apidog CLI
  • Mock server: smart mock/ dynamic response, ไม่ต้อง Express หรือ mock lib อื่น
  • Documentation: auto generate จาก API spec

ย้าย test workflow ไป Apidog จะลด npm dependency หลายสิบตัวใน infra ของคุณ


Layer 7: ตรวจสอบเครือข่ายและ runtime

บล็อกโดเมนอันตรายที่รู้จัก

หลังซัพพลายเชนโจมตี ให้บล็อก infra คำสั่ง/ควบคุมที่ network layer:

# เพิ่มลงใน /etc/hosts
echo "0.0.0.0 sfrclak.com" | sudo tee -a /etc/hosts
Enter fullscreen mode Exit fullscreen mode

ใน CI/CD, จำกัด network egress เฉพาะโดเมนที่จำเป็น (npm registry, git host, deploy target) อื่นๆ block หมด

ใช้ StepSecurity Harden-Runner (สำหรับ CI/CD)

StepSecurity Harden-Runner ตรวจสอบ workflow GitHub Actions แบบเรียลไทม์

ตรวจพบ Axios dropper ติดต่อ C2 ภายใน 1.1 วินาทีหลัง npm install

# GitHub Actions
- uses: step-security/harden-runner@v2
  with:
    egress-policy: audit  # หรือ 'block' สำหรับโหมดเข้มงวด
Enter fullscreen mode Exit fullscreen mode

การตรวจสอบ runtime process

พิจารณา Endpoint Detection and Response (EDR) สำหรับ dev machine

Axios RAT สร้าง process เช่น osascript (macOS), cscript (Windows), python3 (Linux) ระหว่าง npm install

ตั้ง alert pattern สำหรับ subprocess เหล่านี้


ตัวอย่าง .npmrc ที่ปลอดภัย

# Pin exact version
save-exact=true
save-prefix=
# ปิด script lifecycle
ignore-scripts=true
# เปิดใช้งาน provenance
provenance=true
# official registry เท่านั้น
registry=https://registry.npmjs.org/
# require 2FA
auth-type=web
# audit moderate ขึ้นไป
audit-level=moderate
Enter fullscreen mode Exit fullscreen mode

commit ลง repo เพื่อ enforce ให้ทีมใช้ setting นี้


ตัวอย่าง Secure CI/CD Pipeline

name: Secure Build
on: [push, pull_request]
jobs:
  security-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: step-security/harden-runner@v2
        with:
          egress-policy: audit
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      # Layer 1+2: frozen lockfile, no scripts
      - run: npm ci --ignore-scripts
      # Layer 3: check for version drift
      - run: npm ls --all > deps.txt
      # Layer 4: provenance audit
      - run: npm audit signatures
      # Layer 5: behavioral analysis
      - run: npx socket scan
      # Layer 5: vulnerability scan
      - run: npx snyk test
      # Layer 1: baseline audit
      - run: npm audit --audit-level=moderate
      # Build native deps (allowlist)
      - run: npm rebuild sharp bcrypt
Enter fullscreen mode Exit fullscreen mode

มีอะไรใหม่เกี่ยวกับความปลอดภัย npm

การรับรอง provenance ภาคบังคับสำหรับแพ็คเกจยอดนิยม

npm เตรียม require provenance สำหรับแพ็คเกจ top download เพื่อป้องกัน publish manual ด้วย token (สาเหตุ Axios โดน compromise)

การอนุมัติ release แบบสองคน

เหมือนธุรกรรมการเงิน แพ็คเกจใหญ่ต้อง admin สองคน approve ก่อน publish ลดโอกาสโจมตีด้วยบัญชีที่ถูกขโมย

Runtime permission model

Deno จำกัดสิทธิ script (network, fs, env) Node.js กำลังออก permission model ใกล้เคียงในอนาคต สคริปต์ postinstall ต้องขอสิทธิชัดเจน

Package manager isolation

pnpm แยก dependency ดี, package เห็นแค่ dependency ที่ declare เอง ป้องกัน dependency confusion

npm เตรียมนำ isolation แบบเดียวกันมาใช้


FAQ

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

โจมตีซัพพลายเชน npm คือการโจมตีผ่าน dependency chain ไม่ใช่ code ของคุณโดยตรง อาจ hijack maintainer, inject code ใน package ดัง, หรือ typosquat ชื่อคล้ายกัน

ติดตั้ง/อัปเดต dependency = โค้ดอันตรายรันบนเครื่อง dev หรือ CI/CD ขโมย credentials, ติด backdoor, รั่วข้อมูล

npm audit เพียงพอหรือไม่?

ไม่พอ npm audit เช็ค CVE database เท่านั้น Zero-day อย่าง Axios compromise ไม่มีใน CVE ขณะโจมตี

ต้องใช้ behavioral tool เช่น Socket.dev ที่ดูว่า package ทำอะไรบ้าง ใช้ npm audit เป็น baseline, ไม่ใช่ defense เดียว

ต้องเลิกใช้ npm เลยไหม?

ไม่จำเป็น npm ยังเป็น ecosystem ที่ใหญ่ที่สุด ส่วนมากปลอดภัย เป้าหมายคือ "ลดความเสี่ยง" ด้วยการ pin version, enforce lockfile, block script, ลด dependency และใช้ native API เมื่อทำได้

Apidog ลดความเสี่ยง supply chain npm อย่างไร?

Apidog มี HTTP client ในตัว, test runner, mock server, doc generator สำหรับ API dev

ลดความจำเป็นต้องใช้ npm package อย่าง Axios, node-fetch, Jest, Express (mock), และ test dependency อื่นๆ

dependency น้อยลง = vector โจมตีน้อยลงใน workflow ของคุณ

package provenance ใน npm คืออะไร?

Provenance ใช้ Sigstore เชื่อมโยง package กับ repo/source/build CI/CD พิสูจน์ว่า build ที่ไหน/อย่างไร

ตรวจสอบ provenance ด้วย npm audit signatures

package ที่ publish manual จากเครื่อง dev จะขาด provenance ถือเป็น risk สำหรับแพ็คเกจยอด download

npm มีแพ็คเกจอันตรายกี่ตัว?

Snyk ระบุ npm malicious package > 3,000 ตัวในปี 2024

Q4/2025 Sonatype บล็อก malware 120,612 ครั้งใน npm/PyPI/others

ส่วนใหญ่เป็น typosquat, download น้อย แต่กรณี compromise ใหญ่เช่น Axios พิสูจน์ว่าแพ็คเกจใหญ่ก็ไม่รอด

ช่องโหว่ PackageGate คืออะไร?

PackageGate: zero-day หกตัวที่พบ ม.ค. 2026 ใน npm, pnpm, vlt, Bun

หนึ่งในนั้น: git-based dependency อาจรันโค้ดแม้ ignore-scripts=true

ดังนั้นอ้าง git repo ต้อง pin commit hash


สรุปประเด็นสำคัญ

  • Lockfile hygiene คือฐาน แต่นับไม่กัน first install ตอนโจมตี
  • ปิด postinstall script ทั่วโลก (ignore-scripts=true)
  • Pin exact version (save-exact=true) กัน semver drift
  • ตรวจ provenance (npm audit signatures) หาสัญญาณ publish manual
  • ใช้ Socket.dev (behavioral), Snyk (CVE), npm audit (baseline) ร่วมกัน
  • ลด dependency ด้วย native API หรือแพลตฟอร์มรวมเช่น Apidog
  • ตรวจ egress network ใน CI/CD ด้วย StepSecurity Harden-Runner

ทุก dependency คือ trust decision

ยิ่ง dependency น้อย พื้นผิวโจมตีเล็ก

ยิ่งมี layer ป้องกันซ้อนกันมาก, การโจมตีจะยิ่งยาก

Build defense แบบ multi-layer, ไม่ใช่แบบ single point

Top comments (0)