🔥99%人答不全的安全链!第5问必翻车?💥

1. 对安全有什么了解?

前端安全不只是"防XSS",而是纵深防御体系(Defense in Depth)。我总结为"三防三控":

  • 三防:XSS、CSRF、点击劫持
  • 三控:权限控制、输入控制、通信控制

真实业务场景:我们做金融SaaS时,一个富文本编辑器被注入 <script>,导致用户Token泄露------这就是典型的存储型XSS

「Q1: XSS有几种类型?分别怎么防御?」

A1: 分3种:

  • 存储型:服务端入库前转义(如 &lt;)或使用DOMPurify库
  • 反射型:前端不直接 innerHTML,用 textContent
  • DOM型:避免 eval()innerHTML 拼接用户输入
    👉继续看?💥

「Q2: 为什么转义 < > 就能防XSS?」

A2: 因为 <script> 标签需要尖括号解析,转义后浏览器不会当作标签处理,而是纯文本。

⚠️但这不是万能的!比如在 onerror="alert(1)" 中,引号未闭合仍可执行。

「Q3: 前端能完全防住XSS吗?」

A3: ❌不能!前端是"最后一道防线",核心防御应在服务端。前端做双重校验,提升用户体验。


2. 介绍下数字签名的原理

数字签名 = 非对称加密 + 摘要算法,用来验证数据完整性和身份认证。

流程如下(图示):

%% ========================================================= %% 专业级「数字签名流程」可视化 %% 主题:Hash → 私钥加密 → 传输 → 公钥验证 %% 适配:深色 / 浅色模式自适应 %% 图标:FontAwesome 6.5 %% ========================================================= %% 1. 全局样式 %% 2. 节点定义 %% 3. 关键路径高亮 %% 4. 状态颜色编码 %% 5. 动效提示 %% ========== 1. 全局样式 ========== %% 主色:#0ea5e9(sky-500) %% 辅色:#10b981(emerald-500) %% 警告:#f59e0b(amber-500) %% 背景:#ffffff / #111827(自适应) %% 字体:Inter, system-ui, sans-serif %% 圆角:8px %% 阴影:0 4px 6px -1px rgba(0,0,0,0.1) flowchart TD classDef sender fill:#0ea5e9,stroke:#0284c7,color:#fff,stroke-width:2px,rx:8px,ry:8px classDef hash fill:#10b981,stroke:#059669,color:#fff,stroke-width:2px,rx:8px,ry:8px classDef sign fill:#f59e0b,stroke:#d97706,color:#fff,stroke-width:2px,rx:8px,ry:8px classDef transmit fill:#8b5cf6,stroke:#7c3aed,color:#fff,stroke-width:2px,rx:8px,ry:8px classDef receiver fill:#ef4444,stroke:#dc2626,color:#fff,stroke-width:2px,rx:8px,ry:8px classDef verify fill:#22c55e,stroke:#16a34a,color:#fff,stroke-width:2px,rx:8px,ry:8px %% ========== 2. 节点定义 ========== S[" 发送方"]:::sender H[" Hash函数"]:::hash D[" 生成摘要 Digest"]:::hash Sig[" 私钥加密摘要 → 签名"]:::sign T[" 传输"]:::transmit R[" 接收方"]:::receiver H2[" Hash原文 → 新摘要"]:::hash Dec[" 公钥解密签名 → 原摘要"]:::receiver V[" 两摘要比对一致?→ 验证通过"]:::verify %% ========== 3. 关键路径高亮 ========== S -->|原文| H H --> D D --> Sig Sig --> T T --> R R --> H2 R --> Dec H2 --> V Dec --> V %% 关键路径加粗 linkStyle 0 stroke:#0ea5e9,stroke-width:3px linkStyle 1 stroke:#10b981,stroke-width:3px linkStyle 2 stroke:#f59e0b,stroke-width:3px linkStyle 3 stroke:#8b5cf6,stroke-width:3px linkStyle 4 stroke:#ef4444,stroke-width:3px linkStyle 5 stroke:#10b981,stroke-width:3px linkStyle 6 stroke:#ef4444,stroke-width:3px linkStyle 7 stroke:#22c55e,stroke-width:3px linkStyle 8 stroke:#22c55e,stroke-width:3px %% ========== 4. 状态颜色编码 ========== %% 绿色:成功 %% 黄色:签名 %% 红色:接收方 %% 紫色:传输 %% ========== 5. 动效提示 ========== %% 部署时可通过 CSS 实现: %% .node[id*="Sig"]:hover { transform: scale(1.05); } %% .node[id*="V"]:hover { box-shadow: 0 0 10px #22c55e; }

⚠️中间人能篡改吗?👉继续看?

核心代码(简化版):

js 复制代码
// 模拟签名生成(Node.js crypto)
const crypto = require('crypto');

function sign(data, privateKey) {
  const hash = crypto.createHash('sha256').update(data).digest(); // 摘要
  const signature = crypto.privateEncrypt(privateKey, hash);     // 私钥加密
  return signature;
}

function verify(data, signature, publicKey) {
  const hash = crypto.createHash('sha256').update(data).digest();
  const decrypted = crypto.publicDecrypt(publicKey, signature);
  return decrypted.equals(hash); // 比对
}

// 注:实际用 sign/verify 方法,此处为原理演示

「Q4: 为什么不用私钥加密全文?」

A4: 因为非对称加密慢且有长度限制。摘要固定长度(如256位),效率高。

「Q5: 中间人篡改数据+重新签名行吗?」

A5: ❌不行!他没有发送方的私钥,无法生成合法签名。接收方用公钥解密失败或摘要不匹配。


3. 前后端通信使用什么方案?

通信方案按场景分:

场景 方案 说明
普通CRUD RESTful API 标准、易调试
实时数据 WebSocket 如聊天、订单推送
文件传输 FormData + 上传进度 配合断点续传
微前端 Custom Event / postMessage 主子应用通信
高性能 gRPC-Web 内部系统,ProtoBuf序列化

「Q6: REST和gRPC怎么选?」

A6:

  • REST:对外API、调试友好、浏览器原生支持
  • gRPC:内部服务、性能敏感、多语言场景
    👉选错=架构翻车!🤯

4. RESTful常用的Method

Method 幂等 用途
GET 查询
POST 创建
PUT 全量更新
PATCH 部分更新
DELETE 删除

⚠️面试陷阱:POST一定不幂等?

不一定!如果服务端实现为"创建唯一资源",重复提交应返回409 Conflict,也能做到幂等。

「Q7: 幂等性前端怎么保证?」

A7:

  • 前端防抖:按钮点击后禁用
  • 唯一请求ID:后端通过 X-Request-ID 去重
  • Token机制:提交后Token失效

5. 介绍下跨域

跨域是浏览器的同源策略(Same-Origin Policy)导致的,非服务端限制。

同源 = 协议 + 域名 + 端口 相同。

常见跨域场景:

ascii 复制代码
前端: http://localhost:3000
后端: http://api.example.com:8080
       ❌ 协议+域名+端口都不同 → 跨域

解决方案:

  1. CORS(主流):服务端加响应头
  2. JSONP:只支持GET,已淘汰
  3. 代理:开发用webpack proxy,生产用Nginx
  4. postMessage:iframe通信

「Q8: 为什么说跨域是浏览器行为?」

A8: 因为用curl或Postman发请求,根本不受跨域限制。这是浏览器为保护用户安全设计的。

「Q9: 简单请求和预检请求区别?」

A9:

  • 简单请求:GET/POST + text/plain等,直接发
  • 预检请求:带自定义头或复杂类型,先发OPTIONS探路
    👉预检失败=跨域拦住!

6. Access-Control-Allow-Origin在服务端哪里配置?

在服务端HTTP响应头中设置,位置取决于技术栈:

  • Node.js (Express):

    js 复制代码
    app.use((req, res, next) => {
      res.header('Access-Control-Allow-Origin', 'https://yourdomain.com'); // 或 *
      res.header('Access-Control-Allow-Credentials', 'true');
      next();
    });
  • Nginx:

    nginx 复制代码
    location / {
      add_header 'Access-Control-Allow-Origin' 'https://yourdomain.com';
      add_header 'Access-Control-Allow-Credentials' 'true';
    }
  • Java Spring Boot: @CrossOrigin 注解

⚠️配置 * 时不能带 credentials!否则浏览器拒绝。

「Q10: 如何安全地配置允许多个域名?」

A10: 不能写多个头!需动态判断 origin 是否在白名单,再设置对应值。

👉硬编码=安全漏洞!


7. csrf跨站攻击怎么解决?

CSRF:攻击者诱导用户在已登录状态下发起非自愿请求。

比如:<img src="http://bank.com/transfer?to=evil&amount=1000">

解决方案:

  1. SameSite Cookie(推荐):

    http 复制代码
    Set-Cookie: session=abc; SameSite=Lax; Secure
    • Lax:跨站GET允许,POST拦截
    • Strict:完全禁止跨站
  2. CSRF Token

    • 服务端生成 token,前端表单提交时带上
    • 服务端校验 token 是否匹配
  3. 双重提交 Cookie

    • 前端从 cookie 读 token,放入 header 提交
    • 服务端比对 cookie 和 header 中的 token

「Q11: 为什么加 token 就能防CSRF?」

A11: 因为攻击者无法读取 cookie(同源策略),拿不到 token,请求被拒绝。

「Q12: SameSite=Lax 和 Strict 区别?」

A12:

  • Lax:允许导航式GET(如点击链接)
  • Strict:任何跨站都不行,体验差
    👉电商常用 Lax

8. 前端和后端怎么联调?

联调流程的"三阶联调法":

  1. 契约先行:用 Swagger/OpenAPI 定义接口,前端 mock 数据开发
  2. 本地代理:webpack proxy 指向测试环境
  3. 联调环境:共用测试服,用 Charles/Fiddler 抓包

工具链:

  • 接口文档:Swagger / YAPI
  • Mock:MSW(Mock Service Worker)
  • 调试:Chrome DevTools + 日志追踪ID

「Q13: 接口字段不一致怎么处理?」

A13:

  • 用 TypeScript 接口同步定义
  • 自动化生成 DTO,避免手写错误
    👉手动维护=bug温床!

「Q14: 如何快速定位是前端还是后端问题?」

A14:

  • 看请求:数据发出去了吗?格式对吗?
  • 看响应:状态码?数据结构?
  • 看日志:前后端加 traceId 串联
相关推荐
用户102207917571111 分钟前
表格拖拽原生实现
前端·javascript
五月君_12 分钟前
见证历史:Vite 首次超越 Webpack!
前端·webpack·node.js
小old弟12 分钟前
前端开发,Promise 从原理到实现,一文通
前端
nickzone13 分钟前
Next.js + Shopify OAuth 第三方应用接入完整指南
前端
xyphf_和派孔明16 分钟前
web前端React和Vue框架与库安全实践
前端·javascript·前端框架
一只小风华~26 分钟前
JavaScript:Ajax(异步通信技术)
前端·javascript·ajax·web
努力奋斗11 小时前
npm ERR! code CERT_HAS_EXPIRED:解决证书过期问题
前端·npm·node.js
༺๑Tobias๑༻1 小时前
Linux下Redis常用命令
linux·前端·redis
寅时码2 小时前
我开源了一款 Canvas “瑞士军刀”,十几种“特效与工具”开箱即用
前端·开源·canvas
CF14年老兵2 小时前
🚀 React 面试 20 题精选:基础 + 实战 + 代码解析
前端·react.js·redux