NPM安装包前能否查看所有待安装依赖包的发布时长?
npm安装前依赖安全检查实现方案
自定义脚本实现核心需求
你可以通过npm内置命令组合自定义脚本的方式,完全满足安装前全量依赖检查的需求,无需依赖第三方工具:
- 第一步:执行
npm install <待安装包名> --dry-run --json,该命令不会实际安装任何包,会输出JSON格式的完整依赖树信息,包含所有直接、间接依赖的包名和版本号,解决默认--dry-run仅展示直接依赖的问题 - 第二步:解析上述输出的JSON内容,递归提取所有待安装包的
name、version字段 - 第三步:对每个提取到的包版本,执行
npm view <包名>@<版本号> time.<版本号>获取该版本的发布时间,计算和当前时间的差值,若小于24小时则输出警告 - 第四步(可选):额外执行
npm view <包名>@<版本号> scripts,检查是否存在preinstall/install/postinstall等执行钩子,将带钩子的包单独列出来做二次校验
简易Node.js实现示例
const { execSync } = require('child_process'); // 替换为你要安装的包,比如'react-native-gesture-handler@latest' const targetPkg = process.argv[2]; if (!targetPkg) { console.error('请传入要安装的包名'); process.exit(1); } // 获取全量依赖列表 const dryRunRes = JSON.parse(execSync(`npm install ${targetPkg} --dry-run --json`, { encoding: 'utf8' })); const allDeps = new Map(); // 递归提取所有依赖 function extractDeps(deps) { if (!deps) return; Object.values(deps).forEach(dep => { const key = `${dep.name}@${dep.version}`; if (!allDeps.has(key)) { allDeps.set(key, { name: dep.name, version: dep.version }); extractDeps(dep.dependencies); } }) } extractDeps(dryRunRes.dependencies); // 检查每个包的发布时间和钩子 const now = Date.now(); const oneDay = 24 * 60 * 60 * 1000; console.log(`待检查依赖总数:${allDeps.size}\n`); allDeps.forEach(({name, version}) => { // 查发布时间 const publishTimeStr = execSync(`npm view ${name}@${version} time.${version}`, { encoding: 'utf8' }).trim(); const publishTime = new Date(publishTimeStr).getTime(); const diff = now - publishTime; if (diff < oneDay) { console.warn(`⚠️ 风险警告:${name}@${version} 发布时间不足1天,发布时间:${publishTimeStr}`); } // 查install钩子 const scripts = JSON.parse(execSync(`npm view ${name}@${version} scripts --json`, { encoding: 'utf8' })) || {}; const hasDangerHook = ['preinstall', 'install', 'postinstall'].some(hook => scripts[hook]); if (hasDangerHook) { console.log(`ℹ️ 注意:${name}@${version} 包含执行钩子,建议确认安全性`); } })
使用方式:将上述代码保存为npm-check.js,执行node npm-check.js <待安装包名>即可完成检查。
其他npm恶意包防护方案
- 全局禁用执行钩子:执行
npm config set ignore-scripts true,默认禁止所有包的install钩子执行,针对node-sass、sqlite3这类需要本地编译的包,在确认安全后单独执行npm rebuild <包名>触发钩子即可,解决--ignore-scripts参数的可用性问题 - 固定间接依赖版本:在package.json中配置
overrides字段,锁定所有间接依赖的版本,避免意外安装未审核的新版本 - 启用npm签名校验:执行
npm config set audit-signatures true,校验包的发布签名合法性,避免安装被篡改的包 - 配置私有镜像源:使用内部私有npm镜像,仅同步经过安全审核的包版本,避免直接拉取公网新发布的风险包
内容的提问来源于stack exchange,提问作者wotanii
相关产品推荐
相关产品推荐

