Appearance
npm 安全最佳实践
npm安全是现代JavaScript开发中的重要考虑因素。本章将详细介绍如何保护您的npm项目免受安全威胁,包括依赖审计、权限管理、安全配置等方面。
安全威胁类型
恶意包威胁
npm生态系统中可能存在恶意包,常见的威胁包括:
- 数据窃取:收集敏感信息
- 供应链攻击:通过依赖链传播恶意代码
- 挖矿脚本:利用系统资源
- 键盘记录:捕获用户输入
依赖漏洞
- 已知漏洞:包含CVE报告的安全漏洞
- 过时依赖:使用有漏洞的旧版本
- 间接依赖:依赖链中的脆弱包
npm内置安全功能
npm audit
npm内置安全审计功能:
bash
# 检查项目中的安全漏洞
npm audit
# 详细报告
npm audit --audit-level high
# JSON格式输出
npm audit --json
# 仅检查生产依赖
npm audit --production
# 仅检查开发依赖
npm audit --dev
自动修复
bash
# 自动修复兼容的漏洞
npm audit fix
# 安装可能破坏兼容性的修复
npm audit fix --force
# 仅修复特定严重级别的漏洞
npm audit fix --audit-level=moderate
npm audit fix --audit-level=high
npm audit fix --audit-level=critical
# 检查修复结果
npm audit
安全配置
bash
# 配置安全相关设置
npm config set audit true # 启用自动审计
npm config set audit-level low # 设置最低审计级别
npm config set fund false # 禁用funding消息
# 查看安全配置
npm config list | grep audit
依赖安全管理
依赖审查
bash
# 检查所有依赖
npm ls --depth=0
# 检查特定依赖
npm ls package-name
# 检查依赖树
npm ls --depth=Infinity
# 检查过时的包
npm outdated
依赖最小化
json
{
"scripts": {
"check-deps": "npx depcheck",
"unused-deps": "npx npm-check --skip-unused false"
}
}
依赖验证
bash
# 验证包的完整性
npm view package-name --json
# 检查包的发布历史
npm view package-name time
# 检查包的维护者
npm owner ls package-name
包发布安全
账户安全
两因素认证 (2FA)
bash
# 为npm账户启用2FA
npm profile enable-2fa auth-and-writes
# 检查2FA状态
npm profile get 2fa
访问令牌
bash
# 创建访问令牌
npm token create --read-only
npm token create --cidr=192.168.0.1/24 # 限制IP范围
# 列出令牌
npm token list
# 删除令牌
npm token revoke <token>
发布前检查
bash
# 检查将要发布的文件
npm pack --dry-run
# 验证package.json
npm run prepublishOnly
# 检查敏感信息
npx npm-check-updates --error-level 2
权限管理
全局包权限
bash
# 避免使用sudo安装包
# 正确做法:配置npm使用本地目录
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
# 或使用nvm管理Node.js
nvm install --lts
工作目录权限
bash
# 确保项目目录权限正确
chmod 755 .
chmod 644 package.json
chmod 644 package-lock.json
依赖锁定
package-lock.json安全
bash
# 始终提交package-lock.json
git add package-lock.json
# 使用npm ci进行可重现构建
npm ci
# 验证锁文件完整性
npm audit
npm ls
内容安全策略
json
{
"engines": {
"node": ">=16.0.0",
"npm": ">=8.0.0"
},
"scripts": {
"preinstall": "node verify-dependencies.js",
"postinstall": "npm audit --audit-level moderate"
}
}
代码安全扫描
静态代码分析
json
{
"scripts": {
"security:scan": "snyk test",
"security:auth": "snyk auth $SNYK_TOKEN",
"security:monitor": "snyk monitor"
}
}
漏洞扫描工具
bash
# 使用Snyk扫描
npm install -g @snyk/cli
snyk test
snyk monitor
# 使用Retire.js扫描过时依赖
npm install -g retire
retire
# 使用Osano Cookie Scanner
npx @osano/cookie-scanner
安全配置
.npmrc安全配置
# .npmrc
# 禁用脚本执行(实验性功能)
ignore-scripts=true
# 设置审计级别
audit-level=moderate
# 禁用资金推广
fund=false
# 设置超时
fetch-timeout=60000
# 验证SSL
strict-ssl=true
package.json安全配置
json
{
"name": "my-secure-project",
"scripts": {
"preinstall": "node scripts/check-engines.js",
"postinstall": "npm audit --audit-level moderate",
"security": "npm audit && snyk test"
},
"engines": {
"node": ">=16.14.0",
"npm": ">=8.0.0"
},
"engineStrict": true,
"private": true
}
CI/CD安全
GitHub Actions安全
yaml
# .github/workflows/security.yml
name: Security Checks
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
env:
CI: true
- name: Run audit
run: npm audit --audit-level moderate
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
依赖更新自动化
yaml
# .github/workflows/dependabot.yml
name: Dependabot
on: pull_request
permissions:
contents: write
pull-requests: write
jobs:
dependabot:
runs-on: ubuntu-latest
if: ${{ github.actor == 'dependabot[bot]' }}
steps:
- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v1.1.1
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Enable auto-merge for Dependabot PRs
if: ${{steps.metadata.outputs.update-type == 'version-update:semver-patch'}}
run: gh pr merge --auto --merge "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
供应链安全
签名验证
bash
# 验证包签名(实验性功能)
npm config set sign-git-tag true
# 使用Provenance
# 在package.json中添加
{
"publishConfig": {
"provenance": true
}
}
依赖来源验证
bash
# 检查包来源
npm view package-name --json | jq '.versions[].dist.tarball'
# 验证发布者
npm view package-name maintainers
安全监控
持续监控
json
{
"scripts": {
"security:watch": "nodemon --exec 'npm audit'",
"security:daily": "npm audit --json | jq '.metadata.vulnerabilities'",
"security:weekly": "npx npm-check-updates -u && npm audit"
}
}
监控服务集成
bash
# 集成Snyk
snyk monitor --org=my-org --project-name=my-project
# 集成GitHub Security
gh extension install github/gh-sbom
gh sbom
应急响应
漏洞响应计划
json
{
"scripts": {
"security:response": "node scripts/security-response.js",
"security:update": "npm update && npm audit",
"security:rollback": "git reset --hard HEAD~1 && npm ci"
}
}
恶意包处理
bash
# 如果发现恶意包
npm uninstall malicious-package
# 检查受影响的依赖
npm ls malicious-package
# 检查是否已执行恶意代码
find . -name "*.log" -exec grep -l "malicious" {} \;
安全工具推荐
依赖分析工具
bash
# depcheck - 检查未使用的依赖
npx depcheck
# bundlephobia - 检查包大小
npx bundlephobia-cli package-name
# npm-check - 检查过时和未使用的包
npx npm-check
# license check - 检查许可证合规性
npx license-checker --summary
安全扫描工具
bash
# npm audit - 内置安全审计
npm audit
# Snyk - 漏洞扫描
npm install -g @snyk/cli
snyk test
# Retire.js - 检测已知漏洞
npm install -g retire
retire
# Node Security Platform (停止维护,使用npm audit替代)
# npm install -g nsp
# nsp check
安全最佳实践清单
开发阶段
- [ ] 使用
npm audit定期检查漏洞 - [ ] 启用自动审计 (
npm config set audit true) - [ ] 验证第三方包的信誉
- [ ] 最小化依赖数量
- [ ] 使用固定版本或^版本号
- [ ] 检查包的下载量和维护状态
- [ ] 避免使用不维护的包
发布阶段
- [ ] 启用2FA (
npm profile enable-2fa) - [ ] 使用访问令牌而不是密码
- [ ] 验证发布内容 (
npm pack --dry-run) - [ ] 设置适当的引擎要求
- [ ] 检查许可证合规性
运维阶段
- [ ] 定期运行安全扫描
- [ ] 监控依赖更新
- [ ] 设置自动安全通知
- [ ] 实施应急响应计划
- [ ] 定期审查访问权限
通过遵循这些安全最佳实践,您可以显著提高npm项目的整体安全性,减少供应链攻击和其他安全威胁的风险。