实际问题
1. 分子数据缺少输入验证 (高危)
文件: src/renderer/MolecularRenderer.ts:77
代码:
renderMolecule(molecule: Molecule): void {
if (this.isDisposed) return;
// Clear previous molecule
this.clearMolecule();
// Create atoms (balls)
molecule.atoms.forEach(atom => {
const atomMesh = this.createAtomMesh(atom);
this.moleculeGroup.add(atomMesh);
});
// ...
}
问题: renderMolecule 方法直接接受分子数据并渲染,没有对数据进行任何验证。如果传入恶意构造的数据,可能导致:
- 原型污染攻击 (Prototype Pollution)
- 渲染异常导致应用崩溃
- 潜在的 XSS 如果分子数据包含 HTML/JavaScript
2. 原型污染风险 (中危)
文件: src/utils/cpkColors.ts:58-60
代码:
export function getCPKColor(element: string): number {
return CPK_COLORS[element] || DEFAULT_ATOM_COLOR;
}
问题: 如果 element 参数来自不可信来源(如用户上传的分子文件),且值为 __proto__、constructor 或 prototype,可能触发原型污染。
3. 资源释放不完整 (中危)
文件: src/renderer/MolecularRenderer.ts:156-166
代码:
clearMolecule(): void {
while (this.moleculeGroup.children.length > 0) {
const child = this.moleculeGroup.children[0];
if (child instanceof THREE.Mesh) {
child.geometry.dispose();
if (Array.isArray(child.material)) {
child.material.forEach(m => m.dispose());
} else {
child.material.dispose();
}
}
this.moleculeGroup.remove(child);
}
}
问题:
- 只处理了
THREE.Mesh 类型的对象,其他类型(如 THREE.Line, THREE.Points)的资源未被释放
userData 中可能包含的引用未被清理,可能导致内存泄漏
- 没有处理纹理 (Textures) 和渲染目标 (RenderTargets) 的释放
4. CI/CD 配置存在安全风险 (中危)
文件: .github/workflows/deploy.yml:28-29
代码:
- name: Build
run: npm run make || npm run build || echo "No build script"
问题: 使用 || 链式回退会掩盖构建失败,可能导致:
- 安全漏洞的代码被部署到生产环境
- 无法及时发现构建过程中的安全问题
5. 缺少 Electron 安全配置
问题: 项目计划作为 Electron 应用,但缺少必要的安全配置:
- 没有配置
contextIsolation
- 没有配置
sandbox
- 缺少 Content Security Policy (CSP)
- 主进程入口文件
src/main/main.js 在 package.json 中被引用但未找到
改进建议
1. 添加输入验证
// src/utils/validation.ts
export function validateMolecule(molecule: unknown): molecule is Molecule {
if (!molecule || typeof molecule !== 'object') return false;
const m = molecule as Partial<Molecule>;
if (!m.id || !m.name || !Array.isArray(m.atoms) || !Array.isArray(m.bonds)) {
return false;
}
// 验证原子数据
for (const atom of m.atoms) {
if (!validateAtom(atom)) return false;
}
// 验证化学键数据
for (const bond of m.bonds) {
if (!validateBond(bond, m.atoms)) return false;
}
return true;
}
function validateAtom(atom: unknown): atom is Atom {
if (!atom || typeof atom !== 'object') return false;
const a = atom as Partial<Atom>;
// 验证元素符号 - 只允许字母
if (!a.element || !/^[A-Z][a-z]?$/.test(a.element)) return false;
// 验证坐标为有限数字
if (!isFinite(a.x!) || !isFinite(a.y!) || !isFinite(a.z!)) return false;
return true;
}
2. 修复原型污染风险
// src/utils/cpkColors.ts
export function getCPKColor(element: string): number {
// 防止原型污染
if (element === '__proto__' || element === 'constructor' || element === 'prototype') {
return DEFAULT_ATOM_COLOR;
}
return CPK_COLORS[element] || DEFAULT_ATOM_COLOR;
}
export function getAtomRadius(element: string): number {
// 防止原型污染
if (element === '__proto__' || element === 'constructor' || element === 'prototype') {
return DEFAULT_ATOM_RADIUS;
}
return ATOM_RADIUS[element] || DEFAULT_ATOM_RADIUS;
}
3. 改进资源释放
clearMolecule(): void {
const disposeObject = (obj: THREE.Object3D) => {
// 递归处理子对象
if (obj.children) {
obj.children.forEach(child => disposeObject(child));
}
if (obj instanceof THREE.Mesh) {
obj.geometry?.dispose();
const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
materials.forEach(material => {
material?.dispose();
// 释放纹理
Object.values(material).forEach(value => {
if (value instanceof THREE.Texture) {
value.dispose();
}
});
});
}
// 清理 userData
obj.userData = {};
};
while (this.moleculeGroup.children.length > 0) {
const child = this.moleculeGroup.children[0];
disposeObject(child);
this.moleculeGroup.remove(child);
}
}
4. 修复 CI/CD 配置
- name: Build
run: npm run make
- name: Security audit
run: npm audit --audit-level=moderate
continue-on-error: true # 仅记录,不阻断
5. 添加 Electron 安全配置模板
// src/main/main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
function createWindow() {
const mainWindow = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
contextIsolation: true, // 启用上下文隔离
sandbox: true, // 启用沙箱
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false, // 禁用 Node 集成
allowRunningInsecureContent: false,
}
});
// 设置 CSP
mainWindow.webContents.session.webRequest.onHeadersReceived((details, callback) => {
callback({
responseHeaders: {
...details.responseHeaders,
'Content-Security-Policy': ["default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"]
}
});
});
mainWindow.loadFile('index.html');
}
为什么重要
| 风险 |
影响 |
| 原型污染 |
攻击者可能修改对象原型,导致应用逻辑被篡改或拒绝服务 |
| 内存泄漏 |
长时间运行后可能导致应用崩溃,影响用户体验 |
| 构建失败掩盖 |
安全漏洞可能被意外部署到生产环境 |
| 缺少 Electron 隔离 |
恶意分子文件可能获得系统级访问权限 |
优先级
相关 Issue
参考链接
实际问题
1. 分子数据缺少输入验证 (高危)
文件:
src/renderer/MolecularRenderer.ts:77代码:
问题:
renderMolecule方法直接接受分子数据并渲染,没有对数据进行任何验证。如果传入恶意构造的数据,可能导致:2. 原型污染风险 (中危)
文件:
src/utils/cpkColors.ts:58-60代码:
问题: 如果
element参数来自不可信来源(如用户上传的分子文件),且值为__proto__、constructor或prototype,可能触发原型污染。3. 资源释放不完整 (中危)
文件:
src/renderer/MolecularRenderer.ts:156-166代码:
问题:
THREE.Mesh类型的对象,其他类型(如THREE.Line,THREE.Points)的资源未被释放userData中可能包含的引用未被清理,可能导致内存泄漏4. CI/CD 配置存在安全风险 (中危)
文件:
.github/workflows/deploy.yml:28-29代码:
问题: 使用
||链式回退会掩盖构建失败,可能导致:5. 缺少 Electron 安全配置
问题: 项目计划作为 Electron 应用,但缺少必要的安全配置:
contextIsolationsandboxsrc/main/main.js在 package.json 中被引用但未找到改进建议
1. 添加输入验证
2. 修复原型污染风险
3. 改进资源释放
4. 修复 CI/CD 配置
5. 添加 Electron 安全配置模板
为什么重要
优先级
相关 Issue
参考链接