DEV Community

Cover image for Bảo Mật NPM Dependencies: Hướng Dẫn Toàn Diện Bảo Vệ Chuỗi Cung Ứng cho Nhà Phát Triển API
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

Bảo Mật NPM Dependencies: Hướng Dẫn Toàn Diện Bảo Vệ Chuỗi Cung Ứng cho Nhà Phát Triển API

TÓM TẮT

Các cuộc tấn công chuỗi cung ứng NPM đã tăng vọt lên hơn 3.000 gói độc hại chỉ riêng trong năm 2024, và vụ xâm nhập Axios tháng 3 năm 2026 đã chứng minh rằng ngay cả các gói nằm trong top 10 cũng không an toàn. Hướng dẫn này bao gồm mọi lớp phòng thủ mà nhà phát triển API cần: thực thi lockfile, chặn script postinstall, xác minh nguồn gốc, công cụ phân tích hành vi và các lựa chọn kiến trúc giúp thu hẹp bề mặt tấn công của bạn.

Dùng thử Apidog ngay hôm nay

Giới thiệu

Cuộc tấn công chuỗi cung ứng Axios vào ngày 31 tháng 3 năm 2026 không phải là vụ xâm nhập npm đầu tiên. Và nó cũng sẽ không phải là cuối cùng. Nhưng với 83 triệu lượt tải xuống hàng tuần và một RAT (công cụ truy cập từ xa) đa nền tảng được triển khai thông qua một tài khoản bảo trì bị chiếm quyền kiểm soát, đó là tiếng chuông cảnh tỉnh lớn nhất mà hệ sinh thái JavaScript đã nhận được.

Đây là điều làm cho vụ việc này khác biệt so với lời khuyên thông thường “cập nhật các phần phụ thuộc của bạn”: cuộc tấn công Axios đã vượt qua mọi biện pháp phòng thủ truyền thống. Mã độc không nằm trong chính Axios. Nó được tiêm vào thông qua một phần phụ thuộc ảo đã kích hoạt hook postinstall. Lockfile không giúp ích gì nếu bạn chạy npm install trong thời gian cuộc tấn công diễn ra. Việc ghim phiên bản cũng không giúp ích nếu bạn chưa ghim.

Các nhà phát triển API đặc biệt dễ bị tổn thương. Các script kiểm thử, pipeline CI/CD, máy chủ giả lập và client HTTP của bạn đều kéo từ npm. Một gói bị xâm nhập duy nhất trong chuỗi công cụ của bạn có thể làm rò rỉ khóa API, thông tin đăng nhập cơ sở dữ liệu và token đám mây từ máy phát triển của bạn.

💡 Apidog loại bỏ một vector tấn công lớn bằng cách cung cấp một client HTTP tích hợp sẵn để kiểm thử API, vì vậy bạn không cần Axios, node-fetch, hoặc got trong bộ công cụ kiểm thử của mình. Tải xuống Apidog miễn phí để giảm bề mặt phụ thuộc npm của bạn trong khi áp dụng các chiến lược phòng thủ dưới đây.

Hướng dẫn này bao gồm bảy lớp bảo vệ, từ vệ sinh lockfile cơ bản đến phân tích hành vi nâng cao.


Lớp 1: Thực thi lockfile

Tại sao lockfile quan trọng

Lockfile ghi lại phiên bản chính xác của mọi gói và các phần phụ thuộc bắc cầu tại thời điểm cài đặt. Nếu không có lockfile, npm install sẽ phân giải phiên bản mới nhất phù hợp với phạm vi semver của bạn. Nếu package.json của bạn ghi "axios": "^1.14.0" và một phiên bản 1.14.1 độc hại tồn tại trên registry, bạn sẽ nhận được phiên bản độc hại đó.

Các quy tắc

Luôn commit lockfile của bạn. Dù là package-lock.json (npm), yarn.lock (Yarn), pnpm-lock.yaml (pnpm), hay bun.lock (Bun), nó đều thuộc về hệ thống kiểm soát phiên bản.

Sử dụng chế độ cài đặt đông lạnh (frozen installs) trong CI/CD. Không bao giờ chạy npm install trong các môi trường tự động. Hãy sử dụng lệnh tương đương với lockfile đông lạnh:

# 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 xóa node_modules và cài đặt nghiêm ngặt từ lockfile. Nếu lockfile không khớp với package.json, nó sẽ thất bại. Điều này ngăn chặn những bất ngờ trong quá trình phân giải.

Xem xét các thay đổi lockfile trong pull request. Khi một PR sửa đổi package-lock.json, hãy kiểm tra những gì đã thay đổi. Các phần phụ thuộc mới, tăng phiên bản và thay đổi URL registry đều cần được xem xét kỹ lưỡng. Công cụ như Socket.dev có thể gắn cờ các thay đổi lockfile đáng ngờ trong các đánh giá PR.

Khoảng trống của lockfile

Lockfile bảo vệ chống lại việc phân giải phiên bản không mong muốn, nhưng không bảo vệ khỏi lần cài đặt đầu tiên. Nếu bạn khởi tạo dự án hoặc thêm phần phụ thuộc mới đúng lúc diễn ra tấn công, phiên bản độc hại sẽ bị khóa lại. Đây là lý do lockfile chỉ là Lớp 1, không phải duy nhất.


Lớp 2: Vô hiệu hóa script postinstall

Vector tấn công chính

Cuộc tấn công Axios, ua-parser-js, event-stream và nhiều vụ khác đều sử dụng script postinstall để chạy mã độc tùy ý trong quá trình cài đặt. Hook này thực thi trước khi mã ứng dụng của bạn chạy và trước khi bất kỳ công cụ bảo mật nào kịp can thiệp.

Chặn script trên toàn cầu

Thêm vào .npmrc:

ignore-scripts=true
Enter fullscreen mode Exit fullscreen mode

Hoặc qua CLI:

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

Điều này ngăn chặn mọi script vòng đời (preinstall, install, postinstall, prepare) chạy khi cài đặt.

Xử lý các gói cần script

Một số gói như bcrypt, sharp, hoặc sqlite3 cần script postinstall để biên dịch native. Có thể xử lý như sau:

Tùy chọn 1: Chạy script chọn lọc sau khi cài đặt

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

Tùy chọn 2: Danh sách cho phép (npm 10+)

Tạo file .scriptsrc.json:

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

Tùy chọn 3: Dùng binary biên dịch sẵn

Nhiều gói giờ đã hỗ trợ binary sẵn, không cần script biên dịch. Kiểm tra trước khi cấp phép chạy script.

Lưu ý về PackageGate

Vào tháng 1/2026, các lỗ hổng "PackageGate" cho thấy phần phụ thuộc Git có thể mang tệp cấu hình cho phép thực thi mã ngay cả khi đã tắt scripts. Nếu package.json tham chiếu URL Git, hãy ghim vào commit hash cụ thể và kiểm tra nội dung repo.


Lớp 3: Ghim các phiên bản chính xác

Ngừng dùng phạm vi semver

Mặc định, npm install --save thêm tiền tố dấu mũ:

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

Dấu ^ nghĩa là “tương thích với 1.14.0”, và sẽ lấy bản 1.x.x mới nhất—có thể là độc hại.

Cách ghim phiên bản:

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

Cấu hình npm để lưu phiên bản chính xác:

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

Ghi đè phần phụ thuộc bắc cầu

Dùng overrides để kiểm soát phiên bản:

{
  "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

Đánh đổi

Ghim chính xác đồng nghĩa bạn tự tay nâng cấp, không còn tự động vá lỗi nhỏ. Đối với dự án nhạy cảm bảo mật, sự đánh đổi này là hợp lý.


Lớp 4: Xác minh nguồn gốc gói

Nguồn gốc là gì?

Nguồn gốc npm dùng chữ ký Sigstore liên kết gói đã xuất bản với repo nguồn và pipeline CI/CD đã build ra nó. Bằng chứng này giúp xác thực:

  • Repo nguồn nào được dùng
  • Hệ thống CI/CD nào đã build
  • Commit nào kích hoạt build

Cách kiểm tra nguồn gốc

npm audit signatures
Enter fullscreen mode Exit fullscreen mode

Lệnh này xác thực các package đã cài đặt có xác nhận nguồn gốc hợp lệ không.

Bật nguồn gốc khi xuất bản package

Thêm vào CI/CD:

# GitHub Actions example
- 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

Thêm vào .npmrc:

provenance=true
Enter fullscreen mode Exit fullscreen mode

Hạn chế

Provenance là tùy chọn và chỉ chứng minh nơi gói được build, không đảm bảo mã nguồn an toàn tuyệt đối.


Lớp 5: Sử dụng công cụ phân tích hành vi

Không chỉ quét lỗ hổng

Các công cụ như npm audit hay Snyk chỉ kiểm tra các CVE đã biết. Tấn công kiểu zero-day, như Axios, sẽ không phát hiện được.

Công cụ phân tích hành vi kiểm tra hành động thực sự của gói.

Socket.dev

Socket phân tích hành vi cài đặt và runtime. Gắn cờ:

  • Yêu cầu mạng khi cài đặt
  • Truy cập file ngoài thư mục gói
  • Thực thi shell
  • Thu thập biến môi trường
  • Mã bị che khuất

Ví dụ quét bảo mật của Socket.dev

Để sử dụng:

# Cài đặt Socket CLI
npm install -g @socketsecurity/cli

# Quét dự án
socket scan
Enter fullscreen mode Exit fullscreen mode

Snyk

Snyk mạnh về lỗ hổng đã biết, điểm rủi ro, hướng dẫn khắc phục.

# Cài đặt Snyk CLI
npm install -g snyk

# Quét dự án
snyk test
Enter fullscreen mode Exit fullscreen mode

Ví dụ quét lỗ hổng của Snyk

Phối hợp nhiều lớp

Kết hợp cả ba công cụ:

# Cơ bản
npm audit

# Phân tích hành vi
socket scan

# Quản lý lỗ hổng
snyk test
Enter fullscreen mode Exit fullscreen mode

Chạy tất cả trong CI/CD. Phát hiện nghiêm trọng phải chặn build.


Lớp 6: Giảm thiểu bề mặt phụ thuộc

Kiểm tra cây phụ thuộc

# Đếm tổng số phần phụ thuộc
npm ls --all | wc -l

# Kiểm tra trùng lặp
npm ls --all | sort | uniq -c | sort -rn | head -20
Enter fullscreen mode Exit fullscreen mode

Tự hỏi với từng phụ thuộc:

  • Tính năng này Node.js native đã có chưa?
  • Gói này kéo theo bao nhiêu phụ thuộc con?
  • Có thể vendor mã nguồn vào dự án không?

Thay thế native cho các gói phổ biến

Gói Thay thế native Có sẵn từ
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

Đặc biệt cho kiểm thử API

Kiểm thử API thường kéo theo nhiều phụ thuộc (client HTTP, assert, test runner, mock server).

Apidog loại bỏ nhu cầu về nhiều phần phụ thuộc npm

Apidog thay thế toàn bộ stack:

  • Client HTTP: tích hợp sẵn, không cần npm package
  • Khẳng định: builder kiểm thử trực quan
  • Test runner: tự động, hỗ trợ CI/CD qua Apidog CLI
  • Mock server: giả lập thông minh, không cần Express/third-party
  • Tài liệu: tự động từ spec API

Chuyển kiểm thử API sang Apidog giúp loại bỏ hàng chục package npm khỏi stack kiểm thử.

Dùng thử Apidog miễn phí để hợp nhất stack kiểm thử API của bạn.


Lớp 7: Giám sát mạng và thời gian chạy

Chặn tên miền độc hại đã biết

Sau mỗi cuộc tấn công, hãy chặn domain chỉ huy & kiểm soát ở cấp mạng:

# Thêm vào /etc/hosts
echo "0.0.0.0 sfrclak.com" | sudo tee -a /etc/hosts
Enter fullscreen mode Exit fullscreen mode

Trong CI/CD, hạn chế outbound network chỉ cho phép registry, git server, đích triển khai.

StepSecurity Harden-Runner cho CI/CD

StepSecurity Harden-Runner giám sát workflow GitHub Actions theo thời gian thực.

# GitHub Actions
- uses: step-security/harden-runner@v2
  with:
    egress-policy: audit  # hoặc 'block' cho nghiêm ngặt
Enter fullscreen mode Exit fullscreen mode

Giám sát thời gian chạy

Với máy phát triển, dùng EDR để gắn cờ quy trình con bất thường mà Node.js tạo ra: osascript (macOS), cscript (Windows), python3 (Linux) từ trong npm install có thể bị phát hiện.


Cấu hình .npmrc được khuyến nghị

Một file .npmrc mẫu bảo mật:

# Ghim phiên bản chính xác
save-exact=true
save-prefix=

# Vô hiệu hóa script vòng đời
ignore-scripts=true

# Bật nguồn gốc khi publish
provenance=true

# Dùng registry chính thức
registry=https://registry.npmjs.org/

# Yêu cầu 2FA khi xuất bản
auth-type=web

# Ngưỡng mức kiểm toán
audit-level=moderate
Enter fullscreen mode Exit fullscreen mode

Commit file này lên repo để toàn bộ nhóm dùng chung cài đặt bảo mật.


Ví dụ pipeline bảo mật CI/CD

Workflow GitHub Actions thực thi đủ 7 lớp:

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

      # Lớp 1+2: Lockfile đông lạnh, không script
      - run: npm ci --ignore-scripts

      # Lớp 3: Kiểm tra không có version lạ
      - run: npm ls --all > deps.txt

      # Lớp 4: Kiểm tra provenance
      - run: npm audit signatures

      # Lớp 5: Phân tích hành vi
      - run: npx socket scan

      # Lớp 5: Quét lỗ hổng
      - run: npx snyk test

      # Lớp 1: Kiểm toán cơ bản
      - run: npm audit --audit-level=moderate

      # Chỉ rebuild các phụ thuộc native được phép
      - run: npm rebuild sharp bcrypt
Enter fullscreen mode Exit fullscreen mode

Điều gì sẽ đến tiếp theo cho bảo mật npm

Xác nhận nguồn gốc bắt buộc cho các gói phổ biến

npm đang xem xét yêu cầu provenance cho các gói vượt qua ngưỡng tải xuống nhất định, nhằm ngăn xuất bản thủ công bằng token như vụ Axios.

Phê duyệt phát hành hai người

Các gói tải xuống cao có thể phải được hai maintainer phê duyệt trước khi phát hành.

Phạm vi quyền runtime

Deno đã hạn chế quyền truy cập mạng, file, env. Node.js cũng đang nghiên cứu mô hình quyền tương tự: script postinstall sẽ cần xin quyền rõ ràng.

Sự hội tụ của package manager

pnpm đã triển khai cách ly nghiêm ngặt: gói chỉ truy cập phụ thuộc đã khai báo. Khi npm áp dụng tương tự, bề mặt tấn công sẽ giảm tiếp.


Câu hỏi thường gặp

Tấn công chuỗi cung ứng trong npm là gì?

Kẻ tấn công xâm nhập account maintainer, tiêm mã độc vào các gói phổ biến hoặc xuất bản typosquat. Khi bạn cài đặt/cập nhật phụ thuộc, mã độc sẽ thực thi trên máy của bạn hoặc CI/CD pipeline, đánh cắp thông tin đăng nhập, cài backdoor hoặc lấy cắp dữ liệu.

npm audit có đủ để bảo vệ chống lại tấn công chuỗi cung ứng không?

Không. npm audit chỉ quét CVE đã biết. Các tấn công zero-day như Axios sẽ không phát hiện. Cần thêm các công cụ phân tích hành vi như Socket.dev.

Có nên ngừng sử dụng npm hoàn toàn không?

Không. npm vẫn là hệ sinh thái lớn nhất, đa số gói an toàn. Hãy giảm thiểu rủi ro bằng ghim phiên bản, thực thi lockfile, chặn script, giảm phụ thuộc và dùng lựa chọn native khi có thể.

Apidog giúp giảm rủi ro chuỗi cung ứng npm như thế nào?

Apidog cung cấp client HTTP, test runner, mock server, document generator—all-in-one—loại bỏ nhu cầu về các gói npm như Axios, node-fetch, Jest, Express... Giảm số lượng package npm, giảm vector tấn công.

Nguồn gốc gói trong npm là gì?

Nguồn gốc dùng Sigstore liên kết mật mã package đã xuất bản với repo nguồn và CI/CD. Xác minh bằng npm audit signatures. Gói xuất bản thủ công từ máy dev sẽ thiếu nguồn gốc—cảnh báo với các package download cao.

Có bao nhiêu gói npm độc hại?

Năm 2024 Snyk xác định hơn 3.000 gói npm độc hại. Q4/2025, Sonatype chặn 120.612 cuộc tấn công malware trong một quý trên npm, PyPI,... Chủ yếu là typosquat, nhưng các vụ lớn như Axios cho thấy gói nổi tiếng vẫn bị tấn công.

Lỗ hổng PackageGate là gì?

PackageGate là sáu lỗ hổng zero-day công bố tháng 1/2026 ảnh hưởng npm, pnpm, vlt, Bun. Phụ thuộc Git có thể mang config cho phép thực thi mã ngay cả khi đã tắt script. Hãy ghim phụ thuộc Git vào commit hash cụ thể.


Những điểm chính cần ghi nhớ

  • Thực thi lockfile là nền tảng, nhưng không bảo vệ khỏi lần cài đặt đầu tiên khi diễn ra tấn công
  • Vô hiệu hóa script postinstall trên toàn cầu bằng ignore-scripts=true trong .npmrc
  • Ghim phiên bản chính xác với save-exact=true
  • Xác minh nguồn gốc gói với npm audit signatures
  • Kết hợp Socket.dev (phân tích hành vi), Snyk (lỗ hổng đã biết), npm audit (cơ bản)
  • Giảm số lượng phụ thuộc bằng API native Node.js và nền tảng tích hợp như Apidog
  • Giám sát lưu lượng mạng CI/CD với StepSecurity Harden-Runner

Mỗi phần phụ thuộc là một quyết định tin cậy. Càng ít phụ thuộc, bề mặt tấn công càng nhỏ. Xây dựng phòng thủ theo chiều sâu, không chỉ đơn độc một lớp.


Tải xuống ứng dụng

Top comments (0)