跳到主要内容

点击劫持攻击与防御

什么是点击劫持攻击

点击劫持(Clickjacking)是一种视觉欺骗攻击,攻击者通过在合法网页上覆盖透明或半透明的恶意网页,诱导用户点击看似安全的元素,实际上却点击了恶意网页上的元素。

攻击原理

  1. 攻击者创建一个包含iframe的恶意网页
  2. iframe加载目标合法网站
  3. 通过CSS将iframe设置为透明或半透明
  4. 调整iframe位置,使恶意按钮与合法网站的按钮重叠
  5. 诱导用户访问恶意网页并点击特定区域
  6. 用户误以为点击的是合法网站按钮,实际上触发了恶意操作

常见攻击手法

  • 透明iframe覆盖:使用透明iframe覆盖合法网站
  • 图片覆盖:使用图片覆盖网页元素,诱导点击
  • 拖拽劫持:诱导用户拖拽操作,实际执行恶意功能
  • 触屏劫持:针对移动设备的点击劫持变体
  • 点击劫持+XSS:结合XSS漏洞增强攻击效果

防御措施

  1. X-Frame-Options头部:设置X-Frame-Options头部防止iframe嵌入
  2. Content-Security-Policy(CSP):使用CSP的frame-ancestors指令
  3. JavaScript防御:使用JavaScript检测iframe环境
  4. 视觉提示:为可点击元素添加视觉反馈
  5. 用户教育:教育用户识别可疑网页和点击位置
  6. 安全的UI设计:设计不容易被劫持的用户界面

Node.js防御示例

设置X-Frame-Options头部

const express = require('express');
const helmet = require('helmet');
const app = express();

// 方法1: 使用helmet中间件
app.use(helmet.frameguard({
action: 'deny' // 禁止所有iframe嵌入
}));

// 方法2: 手动设置头部
app.use((req, res, next) => {
res.setHeader('X-Frame-Options', 'SAMEORIGIN'); // 只允许同源iframe
next();
});

app.get('/', (req, res) => {
res.send('安全的网页内容');
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Content-Security-Policy配置

const express = require('express');
const app = express();

// 设置CSP头部
app.use((req, res, next) => {
// 只允许同源网站嵌入iframe
res.setHeader('Content-Security-Policy', 'frame-ancestors \'self\'');
next();
});

// 或者完全禁止iframe嵌入
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy', 'frame-ancestors \'none\'');
next();
});

app.get('/', (req, res) => {
res.send('安全的网页内容');
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

JavaScript防御点击劫持

// 客户端JavaScript代码
if (top !== self) {
// 检测到页面被嵌入到iframe中
// 可以选择重定向到顶层窗口
top.location = self.location;
// 或者显示警告信息
document.body.innerHTML = '<h1>警告:此网站不能在iframe中打开</h1>';
}

// 更高级的检测方法
function detectClickjacking() {
const hiddenDiv = document.createElement('div');
hiddenDiv.style.width = '100px';
hiddenDiv.style.height = '100px';
hiddenDiv.style.position = 'absolute';
hiddenDiv.style.top = '-1000px';
document.body.appendChild(hiddenDiv);

// 如果div的offsetTop发生变化,可能存在点击劫持
setTimeout(() => {
if (hiddenDiv.offsetTop !== -1000) {
// 检测到点击劫持尝试
alert('警告:检测到潜在的点击劫持攻击!');
// 可以选择刷新页面或重定向
location.reload();
}
document.body.removeChild(hiddenDiv);
}, 100);
}

detectClickjacking();

检测与响应

  • 使用点击劫持检测工具:如OWASP ZAP、Burp Suite等
  • 安全扫描:定期扫描网站是否存在点击劫持漏洞
  • 头部检查:验证网站是否正确设置了X-Frame-Options和CSP头部
  • 用户报告:建立用户报告机制,及时获取可疑点击事件
  • 应急响应:制定点击劫持攻击应急响应计划,包括更新安全头部和修复漏洞

最佳实践

  • 始终设置X-Frame-Options头部,禁止或限制iframe嵌入
  • 使用Content-Security-Policy的frame-ancestors指令增强保护
  • 在客户端实现JavaScript检测机制作为第二道防线
  • 对敏感操作添加额外的确认步骤
  • 定期进行安全测试,包括点击劫持测试
  • 保持Web服务器和应用程序更新,修复已知漏洞