渲染进程里禁止出现什么代码?(安全意识考察)
考察点
- 从"写出功能"到"写不出漏洞"的安全红线意识
- XSS → 提权链条的理解
参考答案
1. 禁止清单
(1)禁止直接 require Node/Electron 模块
// ❌ 绝对禁止(nodeIntegration 必须保持关闭)
const fs = require('fs');
const { shell } = require('electron');
const { exec } = require('child_process');
渲染进程一旦出现这类代码,说明 nodeIntegration 被打开了——页面任何 XSS 都直接变成系统级 RCE。
(2)禁止不可信数据进 HTML 渲染
// ❌ XSS 入口:IPC/网络/文件来的数据直接 innerHTML
element.innerHTML = await window.api.getTemplate();
// ❌ Vue 的 v-html / React 的 dangerouslySetInnerHTML 同理
<div v-html="remoteContent"></div>
桌面端 XSS 的危害远大于 Web(下一跳就是桥接 API),所以:
- 默认按文本渲染(textContent)
- 富文本必须渲染时用 DOMPurify 消毒
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(untrustedHtml); // 白名单过滤
(3)禁止 eval / new Function / 内联脚本
// ❌ 字符串变代码:XSS 放大器,也违反 CSP
eval(userInput);
new Function('return ' + data)();
CSP 应禁用 'unsafe-eval'(开发环境 HMR 除外,见 CSP 篇)。
(4)禁止在渲染进程拼 shell 命令
// ❌ 把用户输入拼进命令,经桥接发给主进程执行
window.api.runCommand(`convert ${userFileName} output.png`);
// userFileName = "a.png; rm -rf ~" → 命令注入
正确:主进程用 execFile 数组传参 + 参数白名单校验,渲染进程只传语义化参数。
(5)禁止把敏感凭据长期放渲染侧
// ❌ localStorage 存长期 token/密钥(XSS 可读一切 storage)
localStorage.setItem('masterToken', token);
原则:渲染进程持有的凭据生命周期越短越好;刷新令牌等高价值凭据放主进程(keytar 系统钥匙串),渲染侧只持短期 access token。
(6)禁止加载不可信远程内容到特权上下文
// ❌ 主框架直接加载第三方 URL(该窗口有桥接 API)
location.href = 'https://untrusted-third-party.com';
远程内容用独立窗口 + 无 preload 配置加载(见「加载远程 URL 防 XSS」)。
2. 为什么渲染进程是"重点怀疑对象"
攻击链条:
远程内容/用户输入 → XSS → 调用桥接 API → 主进程特权能力 → 系统沦陷
↑
渲染进程是这条链唯一能被攻击者直接触碰的环节
所以代码评审时对渲染进程代码的安全假设是:这里的任何输入都可能是恶意构造的,这里的任何代码都可能被篡改执行。
3. 团队落地手段
- ESLint 规则拦截:
// .eslintrc 渲染进程目录的规则
{
rules: {
'no-restricted-globals': ['error', 'require'],
'no-eval': 'error',
'no-implied-eval': 'error',
}
}
- CSP 防线:
script-src 'self'让内联脚本根本执行不了 - code review 清单:搜
innerHTML、v-html、dangerouslySetInnerHTML、eval逐一确认 - 依赖治理:渲染进程的 npm 依赖也要审计(供应链投毒最终也在渲染进程落地)
面试话术
六条红线:不 require Node(nodeIntegration 保持关闭)、不可信数据不进 HTML(DOMPurify 兜底)、禁 eval 系(配合 CSP)、不拼 shell(参数化 + 主进程白名单)、高价值凭据不留渲染侧(keytar 放主进程)、远程内容不进特权窗口。核心认知:渲染进程是攻击链上唯一能被直接触碰的环节,按"输入皆恶意、代码皆可被篡改"假设来写。
常见追问
- 业务必须渲染富文本(如 markdown)怎么办? 服务端/主进程侧消毒 + 前端 DOMPurify 双保险,渲染在 sandboxed iframe 中进一步隔离。
- localStorage 完全不能用吗? 存偏好设置可以,存凭据不行;敏感态数据考虑 sessionStorage(关窗即清)或主进程保管。