TL;DR — Hook PreToolUse chặn mọi lệnh
npm installmà Claude chạy, block các package có CVE đã biết. Ba lớp bảo vệ: hook audit trước khi install, kiểm tra diff lockfile, và quy tắc pin version trong CLAUDE.md. Cài đặt mất 5 phút. Nhảy tới phần hook config →
⚡ Fix nhanh nhất (30 giây): Không muốn setup hook? Thêm 6 quy tắc vào CLAUDE.md (xem phần CLAUDE.md Rules bên dưới). Chặn 80% rủi ro. Không cần shell script.
Đây là Claude Code hook giúp audit mọi lệnh npm install trước khi nó chạy:
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": ".claude/hooks/npm-audit-check.sh", "timeout": 30 } ] } ] }}🔒 Hook này đang chạy trên project của tôi ngay lúc này. Tôi cài nó ngay ngày tin axios bị compromise. Hook chạy trước cả khi npm bắt đầu resolve dependency, nên RAT payload trong
plain-crypto-jssẽ không bao giờ được thực thi.
Tuần trước, axios@1.14.1 bị cài RAT. Hơn 80 triệu lượt tải mỗi tuần.
Postinstall hook độc hại (script mà npm tự động chạy sau khi install package) gọi về server của attacker trong vòng 2 giây sau khi npm install, trước cả khi npm resolve xong dependencies. Nếu Claude chạy lệnh install trong khoảng 3 tiếng bị compromise, máy bạn đã bị chiếm trước khi bạn kịp đọc output trên terminal.
Hook này sẽ chặn được. Đây là toàn bộ setup.
Tại Sao Vibe Coding Khiến Supply Chain Attack Nguy Hiểm Hơn?
Khi AI agent tự chạy npm install, bước review của con người biến mất hoàn toàn. 41% code viết năm 2025 là do AI tạo hoặc hỗ trợ, theo Stack Overflow 2025 Developer Survey.
Vấn đề không chỉ là package bị xâm nhập. Mà là tốc độ chúng được install mà không ai kiểm tra transitive dependency.
Mô hình thế này: Claude gợi ý một package. Bạn approve. npm install chạy. Một transitive dependency mới lẻn vào. Không ai check nó làm gì.
Vụ axios bị compromise khai thác đúng điều này. Package plain-crypto-js độc hại không phải thứ developer chủ động install. Nó đến như dependency ẩn của một package đáng tin cậy. Đây cũng giống như chấp nhận output của Claude mà không review, chỉ khác là thay vì code lỗi, bạn nhận được remote access trojan.
Không có hook:
Claude: "Tôi sẽ install axios cho HTTP requests"→ npm install axios→ axios@1.14.1 resolve→ plain-crypto-js@4.2.1 postinstall chạy→ RAT gọi về server attacker trong 2 giây→ Bạn thấy "added 3 packages"Có PreToolUse hook:
Claude: "Tôi sẽ install axios cho HTTP requests"→ Hook chặn lệnh Bash→ BLOCKED: install không có --ignore-scripts→ Claude thử lại với --ignore-scripts→ Postinstall attack không bao giờ chạyKey insight: Hơn 99% malware open source năm 2025 nhắm vào npm, với Sonatype phát hiện hơn 800 package liên quan đến Lazarus Group tập trung trên npm (Sonatype Q4 2025). Khi AI agent tự install npm package, chúng đang hoạt động trong hệ sinh thái package bị tấn công nhiều nhất trên internet.
Tại Sao npm Cứ Bị Tấn Công Cùng Một Kiểu?
Vụ axios không phải lời cảnh tỉnh. Nó là chuông báo thứ bảy trong chuỗi tám năm mà npm cứ bấm snooze. Mọi vụ compromise lớn từ 2018 đều khai thác cùng một lỗ hổng cấu trúc: registry tin bất kỳ ai giữ token, và postinstall chạy code tùy ý với quyền user mà không hỏi.
| Năm | Package | Chuyện gì xảy ra | Vector |
|---|---|---|---|
| 2018 | event-stream (2M/tuần) | Kẻ lạ dành vài tháng đóng góp code để lấy trust, inject Bitcoin wallet stealer qua flatmap-stream. Mất 2 tháng mới phát hiện (npm post-mortem) | Social engineering → postinstall |
| 2021 | ua-parser-js (8M/tuần) | Account bị hijack. Cryptominer + password stealer trong 3 version. Tồn tại ~4 giờ (Rapid7) | Account takeover → postinstall |
| 2022 | colors, faker (22M+/tuần) | Maintainer tự phá package của mình. Infinite loop trong colors, xóa sạch code faker. Không cần attacker, burnout mới là mối đe dọa (Sonatype) | Insider threat |
| 2025 T8 | Nx (4.6M/tuần) | Exploit lỗ hổng GitHub Actions workflow để steal npm publish token. Chiến dịch S1ngularity triển khai QUIETVAULT credential stealer, dùng LLM tool có sẵn trên máy nạn nhân (Wiz, Socket) | CI/CD pipeline → postinstall |
| 2025 T9 | chalk, debug +16 (2.6B/tuần) | Phishing maintainer qua email fake 2FA reset. Crypto wallet malware. Vụ tấn công npm lớn nhất tính theo lượt tải (CISA) | Phishing → postinstall |
| 2025 T9-T11 | Shai-Hulud (700+ pkg) | Worm tự nhân bản. Đọc npm token trên máy bạn, tự động backdoor tất cả package bạn maintain, lan exponential. Version 2.0 có dead man’s switch: nếu không replicate hoặc exfiltrate được thì xóa home directory (Datadog, Kaspersky) | Phishing → worm → postinstall |
| 2026 T3 | axios (100M/tuần) | Token classic bị steal, bypass 2FA + OIDC. RAT tự xóa dấu vết và giả version. Tồn tại 3 giờ | Token theft → postinstall |
Nhìn cột “Vector”. Sáu trên bảy vụ kết thúc bằng cùng hai từ: → postinstall. Khác attacker, khác năm, khác điểm đầu vào. Cùng cơ chế thực thi. Tám năm liền.
Phản ứng của npm mỗi lần: unpublish package, publish security stub, viết blog “chúng tôi rất nghiêm túc.” Không thay đổi cấu trúc cách postinstall hoạt động. Không sandbox. Không permission model. Không opt-in. Chỉ có trust.
Sau Shai-Hulud, npm thêm Trusted Publishers và OIDC publishing. Ba tháng sau, axios bị compromise bằng classic token bypass hết tất cả. Bản vá cho vụ trước không chặn được vụ sau.
Thực tế khó chịu: npm provenance vẫn là opt-in. OIDC publishing vẫn là opt-in. Dù npm triển khai mọi đề xuất bảo mật ngày mai, toàn bộ ecosystem cần nhiều năm để adopt. Trong khi đó, AI agent install package ở tốc độ máy.
Bạn có thể đợi npm fix. Mọi người đã đợi từ 2018.
Hoặc bạn tự chặn ở phía mình. Ngay bây giờ. Hôm nay.
Bài này không phải để phân tích chuyện gì đã sai. Rất nhiều người thông minh đã viết post-mortem xuất sắc cho mỗi vụ trong bảng trên. Bài này là về thứ duy nhất thực sự hoạt động ở level developer cá nhân: chặn postinstall execution trước khi nó chạy. Trên máy bạn. Trong CI. Trong workflow AI agent của bạn.
Con số: 99.8% malware open source trong Q4 2025 đến từ npm (Sonatype Q4 2025). Phần lớn malware đó dùng lifecycle scripts (postinstall, preinstall) làm cơ chế thực thi. Chặn một vector đó, bạn loại bỏ phần lớn rủi ro. Không phải 100%. Nhưng đủ để bạn vibe code mà không phải nín thở mỗi lần npm install chạy.
Đây là cách chặn postinstall trong Claude Code cụ thể. Ba lớp, 5 phút, không cần ecosystem thay đổi gì.
Key insight: Sáu trên bảy vụ tấn công supply chain npm lớn từ 2018 đều dùng postinstall scripts làm cơ chế thực thi, từ event-stream steal Bitcoin đến worm Shai-Hulud tấn công 700+ package (CISA, 2025). Chặn postinstall bằng
--ignore-scriptslà defense có impact cao nhất mà developer có thể deploy ngay hôm nay, và nó chỉ cần một flag.
Làm Sao Cài Hook Audit Trước Khi Install?
Thêm hook PreToolUse vào .claude/settings.json, match lệnh Bash chứa npm install hoặc yarn add. Hook chạy shell script kiểm tra xem --ignore-scripts có được dùng không, và block lệnh install nếu thiếu flag này. Nếu bạn chưa biết về Claude Code hooks, đó là các script chạy tự động tại các điểm lifecycle cụ thể, có khả năng chặn thao tác nguy hiểm trước khi chúng xảy ra.
Config đầy đủ trong .claude/settings.json:
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": ".claude/hooks/npm-audit-check.sh", "timeout": 30 } ] } ], "PostToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": ".claude/hooks/post-install-audit.sh", "timeout": 30 } ] } ] }}Script PreToolUse tại .claude/hooks/npm-audit-check.sh:
#!/bin/bash# Chặn lệnh npm install không dùng --ignore-scripts
input=$(cat)tool_name=$(echo "$input" | jq -r '.tool_name // ""')command=$(echo "$input" | jq -r '.tool_input.command // ""')
if [ "$tool_name" != "Bash" ]; then exit 0fi
# Chỉ check lệnh npm/yarn/pnpm installif ! echo "$command" | grep -qE 'npm (install|i )|yarn add|pnpm (add|install)'; then exit 0fi
# Cho phép nếu đã dùng --ignore-scriptsif echo "$command" | grep -q '\-\-ignore-scripts'; then exit 0fi
# Block install không có --ignore-scriptsecho '{"error": "BLOCKED: npm install without --ignore-scripts. Postinstall scripts are the #1 supply chain attack vector (see axios@1.14.1). Rerun with --ignore-scripts."}' >&2exit 2Script PostToolUse tại .claude/hooks/post-install-audit.sh:
#!/bin/bash# Chạy npm audit sau mỗi lệnh install
input=$(cat)tool_name=$(echo "$input" | jq -r '.tool_name // ""')command=$(echo "$input" | jq -r '.tool_input.command // ""')
if [ "$tool_name" != "Bash" ]; then exit 0fi
if ! echo "$command" | grep -qE 'npm (install|i )|yarn add|pnpm (add|install)'; then exit 0fi
audit_output=$(npm audit --json 2>/dev/null)vuln_count=$(echo "$audit_output" | jq -r '.metadata.vulnerabilities.total // 0')
if [ "$vuln_count" -gt 0 ]; then high=$(echo "$audit_output" | jq -r '.metadata.vulnerabilities.high // 0') critical=$(echo "$audit_output" | jq -r '.metadata.vulnerabilities.critical // 0') echo "WARNING: npm audit found $vuln_count vulnerabilities ($critical critical, $high high). Run 'npm audit' for details."fi
exit 0Cho cả hai script quyền execute:
chmod +x .claude/hooks/npm-audit-check.sh .claude/hooks/post-install-audit.shKhi Claude thử chạy npm install axios, hook PreToolUse sẽ block và yêu cầu thêm --ignore-scripts. Claude tự retry với flag đó. Install thành công mà không chạy postinstall script. Sau đó hook PostToolUse chạy npm audit và báo cáo vulnerability đã biết.
Key insight: Sonatype phát hiện 34.319 package malware open source mới trong Q3 2025, tăng 140% so với quý trước, đưa tổng số từ 2019 lên 877.522 (Sonatype Q3 2025). Hook PreToolUse bắt buộc
--ignore-scriptssẽ ngăn RAT của axios@1.14.1 thực thi payload hoàn toàn.
Thử ngay: Copy config trên vào
.claude/settings.jsonvà hai script vào.claude/hooks/. Chạychmod +xcho cả hai. Lần tới Claude thửnpm install, bạn sẽ thấy hook chặn ngay.
📬 Mỗi tuần một tip bảo mật Claude Code. Hooks, CLAUDE.md tricks, và phân tích tấn công thực tế. Không lan man. Đăng ký AI Developer Weekly →
Nếu Package Vượt Qua npm Audit Nhưng Vẫn Là Mã Độc Thì Sao?
npm audit chỉ bắt được CVE đã được báo cáo và thêm vào advisory database. Các vụ compromise zero-day như axios@1.14.1 sẽ không xuất hiện trong database trong nhiều giờ. Advisory cho axios được thêm vào sau khi version độc hại đã bị gỡ khỏi npm. Lớp bảo vệ thứ hai bắt được điều audit bỏ lỡ: diff lockfile để phát hiện dependency mới cần review.
Thêm git pre-commit hook này:
#!/bin/bash# .git/hooks/pre-commit (hoặc .husky/pre-commit)# Phát hiện dependency mới thêm vào từ commit trước
lockfile_diff=$(git diff --cached --name-only | grep -E 'package-lock\.json|yarn\.lock|pnpm-lock\.yaml')
if [ -z "$lockfile_diff" ]; then exit 0fi
new_deps=$(git diff --cached package-lock.json \ | grep -E '^\+.*"resolved":' | head -20)
if [ -n "$new_deps" ]; then echo "" echo "Phát hiện dependency mới trong lockfile:" echo "$new_deps" | head -10 echo "" echo "Review trước khi commit. Transitive dependency mới" echo "là cách supply chain attack ẩn mình." echo "" echo "Bỏ qua: git commit --no-verify" exit 1fi
exit 0Script này bắt trường hợp npm audit báo sạch nhưng một transitive dependency mới, chưa được review, đã lẻn vào. Vụ axios đưa vào plain-crypto-js, một package chưa từng xuất hiện trong lockfile nào. Diff lockfile sẽ phát hiện ngay lập tức.
Key insight: 80% dependency của ứng dụng không được upgrade trong hơn 1 năm, dù 95% component có lỗ hổng đã có bản sửa (Sonatype 2024). Diff lockfile bắt dependency mới, có thể là mã độc, ngay lúc commit, không phải vài tuần sau trong đợt audit định kỳ.
Nhận tips Claude Code hàng tuần. Mỗi tuần một email. Tips thực tế, không lan man. Đăng ký AI Developer Weekly →
Có Thể Dùng Agent Hook Để Phân Tích Sâu Hơn Không?
Có. Agent hooks của Claude Code tạo một Claude instance riêng với quyền truy cập Read, Grep, và Glob. Agent hook có thể phân tích transitive dependency mới bằng cách đọc metadata, kiểm tra ngày publish, và so sánh lockfile với trạng thái trước. Đây là lớp bảo vệ kỹ nhất, nhưng tốn token mỗi lần chạy.
{ "hooks": { "PostToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "agent", "prompt": "A Bash command just ran: $ARGUMENTS. If it was an npm/yarn/pnpm install command, read package-lock.json and identify any NEW dependencies not present before. For each new dependency, check: does it have a postinstall script? How many weekly downloads does it have? Was it published in the last 7 days? Flag anything suspicious.", "timeout": 120 } ] } ] }}Đánh đổi là chi phí. Agent hook dùng khoảng 5-10K token mỗi lần chạy. Dùng shell hook cho mọi lần install. Chỉ dùng agent hook cho CI pipeline hoặc project bảo mật cao, nơi phân tích thêm đáng giá chi phí bỏ ra.
Key insight: 53% team đã ship code do AI tạo sau đó phát hiện lỗi bảo mật vượt qua review ban đầu (Veracode 2025). Agent hook thêm một lớp AI reviewer riêng cho rủi ro dependency, bắt được những gì human review và static audit đều bỏ lỡ.
Nên Thêm Quy Tắc Gì Vào CLAUDE.md?
Pin version chính xác và bắt buộc --ignore-scripts ở cấp instruction. Thêm các quy tắc sau vào CLAUDE.md của project để Claude tuân thủ trong mọi session, bất kể cấu hình hook:
## npm Security Rules
- ALWAYS use `--ignore-scripts` with npm install- ALWAYS use `--save-exact` to pin exact versions- NEVER install a package without checking its npm page first- If a package has fewer than 1,000 weekly downloads, ASK before installing- If a package was first published within the last 30 days, ASK before installing- Prefer well-known packages over unknown alternativesQuy tắc --save-exact quan trọng vì vụ axios nhắm vào version 1.14.1 cụ thể. Nếu lockfile pin ở 1.14.0, bạn an toàn. Version range như ^1.14.0 sẽ resolve thành 1.14.1 ở lần clean install tiếp theo.
Để xem thêm về bảo vệ file nhạy cảm khi dùng Claude Code, đọc Cách Tôi Bảo Vệ Code Nhạy Cảm Trên Dự Án Thực Tế.
Key insight: Supply chain compromise chiếm 15% tổng số vụ data breach với chi phí trung bình $4.91 triệu mỗi vụ, thời gian phát hiện trung bình 267 ngày (IBM Cost of a Data Breach 2025). Pin version chính xác trong CLAUDE.md và bắt buộc
--ignore-scriptsmặc định là hai quy tắc miễn phí nhưng loại bỏ được các vector tấn công phổ biến nhất.
Câu Hỏi Thường Gặp
Hook này có hoạt động với pnpm và yarn không?
Có. Thay đổi grep pattern trong script cho đúng package manager:
# Cho pnpmif ! echo "$command" | grep -qE 'pnpm (add|install)'; then
# Cho yarnif ! echo "$command" | grep -qE 'yarn (add|install)'; thenYarn 2+ (Berry) dùng --skip-builds thay vì --ignore-scripts. Điều chỉnh flag check tương ứng.
Có làm chậm workflow không?
Shell hook thêm 1-2 giây mỗi lệnh install. Agent hook thêm 10-15 giây. RAT của axios đánh cắp npm token, SSH key, và cloud credential của bạn trong 2 giây. Đánh đổi rõ ràng.
Nếu dùng Claude Code ở auto-accept mode thì sao?
Hook chạy bất kể permission mode. Đó là mục đích của nó. Ngay cả ở auto-accept mode, hook PreToolUse với exit 2 vẫn block tool call trước khi nó chạy. Đây là lưới an toàn khi bạn đã tắt manual review. Tôi học bài này qua trải nghiệm đau thương với việc xóa file: hãy test threat model thật, không phải threat model bạn tưởng tượng.
Có kết hợp được với Snyk hoặc Socket không?
Có. Thay npm audit bằng tool bạn muốn trong post-install script:
# Snyksnyk test --json 2>/dev/null
# Socketsocket npm audit 2>/dev/nullCùng exit code contract. Zero nghĩa là sạch, non-zero nghĩa là có vấn đề.
Cursor có tính năng tương tự không?
Không. Đây là khác biệt kiến trúc, không phải thiếu tính năng.
| Cursor | Claude Code | |
|---|---|---|
| Cơ chế | .cursorrules (prompt only) | Hooks (process-level) |
| Chặn được lệnh? | Chỉ gợi ý | exit 2 = blocked |
| Hoạt động ở auto-accept? | N/A | Luôn luôn |
Cursor có thể nói “cẩn thận với dependency.” Claude Code có thể giết lệnh trước khi nó chạy. Đây không phải thiếu tính năng. Đây là kiến trúc khác. Không có workaround cho Cursor.
Setup Nhanh: 5 Phút Là Xong
# 1. Tạo thư mục hooksmkdir -p .claude/hooks
# 2. Lưu hai script (copy từ các section ở trên)# .claude/hooks/npm-audit-check.sh (PreToolUse)# .claude/hooks/post-install-audit.sh (PostToolUse)
# 3. Cho quyền executechmod +x .claude/hooks/*.sh
# 4. Thêm hook config vào .claude/settings.json# (copy JSON block từ "Làm Sao Cài Hook Audit Trước Khi Install")
# 5. Thêm npm security rules vào CLAUDE.md# (copy từ "Nên Thêm Quy Tắc Gì Vào CLAUDE.md")Lần tới Claude chạy npm install, hook sẽ block và bắt buộc --ignore-scripts tự động.
📬 Nhận tips Claude Code hàng tuần. Security hooks, workflow tricks, và phân tích tấn công thực tế. Mỗi tuần một email. Đăng ký AI Developer Weekly →
Đọc Thêm
- Claude Code Hooks: Tính Năng Mạnh Không Ai Nói Đến — hướng dẫn đầy đủ 17 hook event và 4 loại handler
- Claude Code Có 17 Hook Event Rồi — agent hooks, prompt hooks, và 7 recipe copy-paste
- Tôi Cài 3 Lớp Phòng Thủ. Claude Vẫn Xóa File Tôi. — tại sao test threat model thật quan trọng hơn thêm nhiều lớp bảo vệ