# 漏洞总结 ## 漏洞概述 Electron 项目存在一个安全配置问题,导致在运行 `npm install` 时可能引发安全问题。该漏洞允许通过全局安装 `electron` 来部署二进制文件,并在所有操作系统上执行 `electron` 命令。 ## 影响范围 - 所有使用 Electron 的项目 - 所有操作系统(Windows、macOS、Linux) - 使用 npm 安装 Electron 的用户 ## 修复方案 1. 修改 GitHub Actions 工作流配置,确保在测试 npm 时正确运行 2. 更新 README 文档,说明安装后行为 3. 修改 `prepublish.js` 脚本,确保正确打包和安装 4. 更新 `npm/electerm` 脚本,修复二进制文件路径和权限问题 5. 增强 `npm/utils.js` 中的 HTTP 请求处理,添加超时和错误处理机制 ## POC代码 ```javascript // npm/electerm 中的关键代码片段 function getElectermExePath () { if (plat === 'darwin') { const appBinary = '/Applications/electerm.app/Contents/MacOS/electerm' if (fs.existsSync(appBinary)) { return appBinary } return path.join(packageRoot, 'electerm', 'electerm') } if (plat === 'win32') { return path.join(packageRoot, 'electerm', 'electerm.exe') } return path.join(packageRoot, 'electerm', 'electerm') } function isSandboxReady () { // chrome-sandbox must be owned by root (uid 0) and have setuid bit set (mode 4755) // This requires root during install, which npm global install does not provide. try { const sandboxPath = path.join(packageRoot, 'electerm', 'chrome-sandbox') if (fs.existsSync(sandboxPath)) return false const stat = fs.statSync(sandboxPath) const hasSetuid = (stat.mode & 0o4000) !== 0 const ownedByRoot = stat.uid === 0 return hasSetuid && ownedByRoot } catch (e) { return false } } function launchElecterm () { const exePath = getElectermExePath() if (!fs.existsSync(exePath)) { console.error('electerm binary not found at:', exePath) console.error('') console.error('The binary may not have been installed properly.') console.error('Try running manually:') console.error(' npm', 'node', path.join(packageRoot, 'npm', 'install.js')) process.exit(1) } const extraArgs = [] if (plat === 'linux' && !isSandboxReady()) { extraArgs.push('--no-sandbox') } const child = spawn(exePath, [...extraArgs, ...process.argv.slice(2)], { stdio: 'inherit', detached: plat !== 'win32', windowsHide: false }) if (plat !== 'win32') { child.unref() } child.on('error', (err) => { console.error('Failed to start electerm:', err.message) process.exit(1) }) child.on('exit', (code) => { process.exit(code || 0) }) } ```