点击劫持攻击与防御
什么是点击劫持攻击
点击劫持(Clickjacking)是一种视觉欺骗攻击,攻击者通过在合法网页上覆盖透明或半透明的恶意网页,诱导用户点击看似安全的元素,实际上却点击了恶意网页上的元素。
攻击原理
- 攻击者创建一个包含iframe的恶意网页
- iframe加载目标合法网站
- 通过CSS将iframe设置为透明或半透明
- 调整iframe位置,使恶意按钮与合法网站的按钮重叠
- 诱导用户访问恶意网页并点击特定区域
- 用户误以为点击的是合法网站按钮,实际上触发了恶意操作
常见攻击手法
- 透明iframe覆盖:使用透明iframe覆盖合法网站
- 图片覆盖:使用图片覆盖网页元素,诱导点击
- 拖拽劫持:诱导用户拖拽操作,实际执行恶意功能
- 触屏劫持:针对移动设备的点击劫持变体
- 点击劫持+XSS:结合XSS漏洞增强攻击效果
防御措施
- X-Frame-Options头部:设置X-Frame-Options头部防止iframe嵌入
- Content-Security-Policy(CSP):使用CSP的frame-ancestors指令
- JavaScript防御:使用JavaScript检测iframe环境
- 视觉提示:为可点击元素添加视觉反馈
- 用户教育:教育用户识别可疑网页和点击位置
- 安全的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服务器和应用程序更新,修复已知漏洞