Skip to content

前端安全考察二

前端安全考察

一、修正你的笔记(先纠偏,再深化)

你的笔记原文问题/建议修正后专业表述
XSS(XSS 注入)表述略简略XSS(跨站脚本攻击):攻击者通过在网页中注入恶意脚本,窃取用户 Cookie、会话令牌,或执行非授权的操作。分为存储型、反射型、DOM型。
攻击者操作 DOM这是 DOM 型 XSS 的特征,不足以概括所有 XSS危害:窃取用户信息、劫持会话、篡改页面内容、发起 DDoS。
Secure:防止暴力破解概念混淆。Secure 与暴力破解无关。Secure:Cookie 的 Secure 属性指示浏览器仅通过 HTTPS 协议传输 Cookie,防止在 HTTP 明文传输中被窃听(中间人攻击)。
CSRFP❌ 拼写错误CSRF(跨站请求伪造):攻击者诱导用户点击恶意链接,携带用户的认证 Cookie 发起非本意的请求(如修改密码、转账)。
流量混淆概念较模糊跨域请求(CORS):浏览器同源策略(Same-Origin Policy)限制脚本跨域访问资源。配置 CORS 头或使用 JSONP(已过时)解决。
wlsockot❌ 拼写错误WebSocket:WebSocket 协议不受同源策略限制(但可以被 Origin 头校验),需使用 wss://(WebSocket over TLS) 加密传输。
依赖混淆攻击表述不准确供应链攻击(依赖混淆):攻击者在公共 NPM 仓库上传与内部包同名的恶意包,或篡改依赖版本,导致 CI/CD 构建时拉取恶意代码。防御:使用私有 NPM 仓库 + 锁文件(package-lock.json)+ 定期 npm audit

二、结构化梳理(面试时按这个逻辑讲)

面试官问“前端安全你了解哪些?”——你按 “4 层防御体系” 来答,层层递进,清晰有力:

第一层:数据与输入防御(XSS)

  • 核心原则:永远不信任用户输入。
  • 防御手段:输入校验 + 输出编码(转义/消毒)。
  • Cookie 三件套HttpOnly(防 XSS 窃取)、Secure(防中间人)、SameSite(防 CSRF 伪造)。
  • CSRF 三件套:SameSite Cookie、CSRF Token、双重 Cookie 验证 + 关键操作二次验证(如验证码)。

第三层:传输与跨域防御(CORS + WebSocket)

  • CORS 最小化原则:只允许必要的源、方法、请求头。
  • WebSocket 安全:使用 wss:// + Origin 头校验 + 短时效 Token。

第四层:供应链与依赖防御(第三方库安全)

  • 防御手段:私有 NPM 仓库、锁文件、依赖审计(npm audit)、镜像源校验。

话术:“在 WeLink IM 中,用户消息支持富文本(加粗、斜体、链接)。我们绝对不信任用户输入,所有富文本消息在渲染前会经过 DOMPurify 消毒,只允许白名单标签(<b><i>a 标签仅允许 href,禁止 onerror 等事件属性)。此外,所有 Cookie 都设置了 HttpOnly,即使出现 XSS 漏洞,攻击者也无法通过 document.cookie 窃取会话令牌。”

代码示例

javascript
import DOMPurify from 'dompurify';

// WeLink 消息渲染前消毒
function sanitizeMessage(content) {
  return DOMPurify.sanitize(content, {
    ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'span'],
    ALLOWED_ATTR: ['href', 'class', 'target'],
    ALLOWED_URI_REGEXP: /^(https?|mailto):/i, // 只允许 http/https/mailto 协议
  });
}

// 在 React 组件中
<div dangerouslySetInnerHTML={{ __html: sanitizeMessage(msg.content) }} />

额外补充(重要):CSP(内容安全策略)是 XSS 的终极防御,也是大厂必配。

“除了代码层,WeLink 生产环境还配置了严格的 CSP(内容安全策略) 响应头,限制只能加载同域脚本和指定 CDN,禁止 eval()inline script。即使 XSS 注入成功,恶意脚本也跑不起来。”
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.xxx.com; object-src 'none'

话术:“在 WeLink 中,我们所有认证 Cookie 都强制配置以下属性:

  • HttpOnly:禁止 JavaScript 读取 Cookie,抵御 XSS 窃取。
  • Secure:仅 HTTPS 传输,防止中间人攻击。
  • SameSite=Lax:跨站请求(如从外部链接点击进入)不携带 Cookie,有效防御 CSRF。”

服务器端设置示例(Node.js / Express):

javascript
res.cookie('sessionId', token, {
  httpOnly: true,   // JS 无法读取
  secure: true,     // 仅 HTTPS
  sameSite: 'lax',  // 顶级导航允许,跨站 POST 禁止
  maxAge: 7 * 24 * 60 * 60 * 1000
});

3. CSRF 防御 —— 双重保障

话术:“虽然 SameSite=Lax 能防御大部分 CSRF,但为了兼容老旧浏览器,我们还在敏感操作(修改密码、生成报告) 中增加了 CSRF Token。服务端下发随机 Token,前端在请求头 X-CSRF-Token 中携带,后端校验。”

代码示例(前端 Axios 自动注入):

javascript
// 从 meta 标签读取服务端注入的 CSRF Token
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content;

axios.interceptors.request.use((config) => {
  if (['post', 'put', 'patch', 'delete'].includes(config.method)) {
    config.headers['X-CSRF-Token'] = csrfToken;
  }
  return config;
});

话术:“WeLink IM 的 WebSocket 连接,我们做了三层安全加固:

  1. 传输层:强制使用 wss://(WebSocket over TLS),加密所有消息。
  2. 连接层:服务端校验请求头中的 Origin,只允许白名单域名。
  3. 鉴权层:连接 URL 中携带短时效 Token(由登录接口下发,有效期 5 分钟),防止重放攻击。”
javascript
// 前端 WebSocket 连接示例(简化)
const ws = new WebSocket(`wss://im.weixin.qq.com/ws?token=${shortLivedToken}`);

// 服务端伪代码(校验 Origin + Token)
ws.on('connection', (req) => {
  const origin = req.headers.origin;
  if (!allowedOrigins.includes(origin)) return ws.close(); // 拒绝非法跨域
  const token = req.url.query.token;
  if (!verifyToken(token)) return ws.close(); // Token 无效或过期
  // 建立连接...
});

5. 供应链安全 —— 依赖审计

话术:“在 WeLink 项目中,我们使用 私有 NPM 仓库(内部镜像),所有依赖包经过安全扫描后才允许引入。CI 流程中强制运行 npm audit高危漏洞必须修复才能合入代码。每周还会做一次依赖版本审查,防止被恶意包替换。”

bash
# CI 流程中的命令
npm audit --production
# 或使用更严格的安全工具
npm audit --audit-level=high

四、面试完整话术(“安全”这一块,你直接全文背诵)

“面试官,我在 WeLink 项目中,从 4 个维度构建了前端安全防御体系:

第一,XSS 防御。所有用户输入,在渲染前必须经过 DOMPurify 消毒,只保留白名单标签和安全的 href。同时全站开启 CSP(内容安全策略),限制脚本来源,即使注入也无法执行。所有 Cookie 强制设置 HttpOnly,让 XSS 攻击者拿不到敏感凭证。

第二,CSRF 防御。我们采用 三管齐下:认证 Cookie 设置 SameSite=Lax;敏感操作(如修改密码、生成报告)额外携带 CSRF Token,由后端下发生成;关键操作配合验证码或二次确认。在 IRMP 报告生成中,我们还引入了幂等键,防止重复提交导致的数据混乱。

第三,传输与跨域安全。WebSocket 长连接强制使用 wss:// 加密,服务端严格校验 Origin,并配合短时效 Token 进行连接鉴权。CORS 跨域配置遵循最小权限原则,只开放必要的域名、方法和请求头。

第四,供应链安全。所有依赖通过私有 NPM 仓库引入,CI 流程中强制运行 npm audit 定期检查,确保没有已知漏洞。我们还会定期审查 package-lock.json 的变更,防止恶意包替换。

总结:安全是‘纵深防御’,没有一招制敌,而是多层防线环环相扣。我设计的方案就是让攻击者突破一层后还有一层,层层设防。”

五、最后的“认知升华”(让面试官觉得你懂安全本质)

“面试官,我理解前端安全的本质是 ‘信任边界的管理’ ——我们要明确哪些数据来自可信来源(服务端),哪些来自不可信来源(用户、第三方),然后在不同边界上设置不同的防御策略。这也是为什么我在 WeLink 的设计中,对用户输入永远保持‘零信任’,而对服务端下发的 Token 则依赖 HttpOnly + Secure 来保护。”

最近更新