前端安全-ClickJacing+sniffing+XSLeaks
字数 1989 2025-10-01 14:05:44
前端安全:ClickJacking、MIME Sniffing 与 XS-Leaks 攻击与防御技术解析
1 ClickJacking(点击劫持)
1.1 攻击原理
ClickJacking 是一种视觉欺骗攻击技术,攻击者通过覆盖透明层诱导用户执行非预期操作。核心步骤包括:
- 嵌入目标页面:使用
<iframe>或其他嵌入标签将目标网页加载到恶意页面中 - 视觉隐藏:通过 CSS 将目标页面透明度设置为极低值(如
opacity: 0.001)或使用定位隐藏 - 诱导交互:欺骗用户在看似无害的页面上进行操作,实际触发目标页面的功能
1.2 攻击示例
<!-- 恶意页面代码 -->
<style>
iframe {
opacity: 0.001;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
}
</style>
<iframe src="https://target-site.com/sensitive-action"></iframe>
<!-- 覆盖在iframe上的欺骗性内容 -->
1.3 防御措施
1.3.1 X-Frame-Options HTTP 头
DENY:完全禁止被嵌入X-Frame-Options: DENYSAMEORIGIN:仅允许同源嵌入X-Frame-Options: SAMEORIGINALLOW-FROM:指定允许的源(部分浏览器已废弃)X-Frame-Options: ALLOW-FROM https://trusted-site.com
1.3.2 Content-Security-Policy (CSP)
- 完全禁止嵌入:
Content-Security-Policy: frame-ancestors 'none'; - 仅允许同源嵌入:
Content-Security-Policy: frame-ancestors 'self'; - 允许特定源嵌入:
Content-Security-Policy: frame-ancestors https://trusted-site.com;
2 MIME Sniffing(MIME 类型嗅探)
2.1 技术原理
浏览器通过 MIME sniffing 机制自动推断响应内容的类型:
- 当服务器未提供
Content-Type头或类型不正确时 - 浏览器分析内容开头字节模式判断文件类型
- 不同浏览器有差异化的嗅探算法
2.2 攻击向量
2.2.1 类型混淆攻击
上传 .png 文件但包含恶意脚本:
// 恶意PNG文件实际内容
<script>alert('XSS')</script>
当服务器未正确设置 Content-Type 或配置错误时,浏览器可能将其解析为 HTML/JS。
2.2.2 脚本加载漏洞
<script src="https://example.com/user-uploaded-file.png"></script>
若服务器错误配置,浏览器可能将非JS文件当作JS执行。
2.3 防御措施
2.3.1 服务器端配置
- 始终提供正确的
Content-Type响应头 - 配置服务器禁止嗅探行为:
X-Content-Type-Options: nosniff
2.3.2 内容安全策略
Content-Security-Policy: script-src 'self'
3 XS-Leaks(跨站泄漏)
3.1 基本概念
XS-Leaks 利用Web平台的侧信道信息推断用户敏感信息,属于旁路攻击范畴。
3.2 攻击技术
3.2.1 基于资源加载的检测
// 检测用户登录状态示例
const img = new Image();
img.onload = () => {
// 用户已登录(加载成功)
console.log('User is logged in');
};
img.onerror = () => {
// 用户未登录(加载失败)
console.log('User is not logged in');
};
// 尝试加载需要认证的资源
img.src = 'https://social-site.com/profile-image.png';
3.2.2 基于状态码的检测
const script = document.createElement('script');
script.onload = () => {
// 状态码为200,即使内容非JS也不会触发onerror
console.log('Request succeeded (200)');
};
script.onerror = () => {
// 请求失败(非200状态码)
console.log('Request failed (non-200)');
};
script.src = 'https://target-site.com/sensitive-endpoint';
document.head.appendChild(script);
3.2.3 基于帧数量的检测
// 通过iframe数量推断页面状态
const iframeCount = window.frames.length;
console.log(`Current frame count: ${iframeCount}`);
3.2.4 Cache Probing(缓存探测)
3.2.4.1 基本原理
通过测量资源加载时间判断是否缓存:
function measureLoadTime(url) {
const start = performance.now();
return fetch(url, { cache: 'force-cache' })
.then(() => performance.now() - start);
}
// 快速加载表明存在缓存(用户已访问过)
// 慢速加载表明无缓存(用户未访问)
3.2.4.2 增强版缓存探测
结合错误事件提高准确性:
- 清除缓存:通过发送超大请求头触发服务器错误(4xx/5xx)
- 加载目标资源:诱导用户访问目标页面
- 检测缓存状态:通过错误事件判断是否存在缓存
// 清除缓存技巧:发送超大请求头
fetch('https://target-site.com/clear-cache', {
headers: { 'X-Oversized': 'A'.repeat(10000) }
});
// 检测缓存存在性
const img = new Image();
img.onload = () => console.log('Cached - user visited');
img.onerror = () => console.log('Not cached - user not visited');
img.src = 'https://target-site.com/cached-resource.png';
3.2.5 Cache Partitioning 绕过
Chrome的缓存分区机制基于:
- Top-level site(顶级站点)
- Current-frame site(当前框架站点)
- Resource URL(资源URL)
绕过方法:使用相同eTLD+1域下的子域发起攻击
- 从
https://app.target.com加载的资源 - 可从
https://other.target.com探测缓存状态
3.3 防御措施
3.3.1 Cookie 保护
Set-Cookie: sessionid=abc123; SameSite=Lax; Secure; HttpOnly
3.3.2 资源隔离
Cross-Origin-Resource-Policy: same-origin
3.3.3 Fetch Metadata 利用
浏览器自动添加的请求头:
Sec-Fetch-Site: 请求源与目标关系(same-origin/same-site/cross-site)Sec-Fetch-Mode: 请求模式(cors/no-cors/navigate)Sec-Fetch-Dest: 请求目标(image/script/style)
服务器端验证:
// 检查请求来源是否合法
if (request.headers['sec-fetch-site'] !== 'same-origin') {
return rejectRequest();
}
3.3.4 统一状态码
将成功和失败响应都返回200状态码,消除状态码差异。
3.3.5 随机化响应时间
添加随机延迟,使时间侧信道攻击失效。
4 实战注意事项
- 组合利用:实际攻击中常组合多种技术提高成功率
- 浏览器差异:不同浏览器对MIME嗅探、缓存处理等有差异
- 性能考量:侧信道攻击需要大量请求,可能被速率限制检测
- 隐私保护:这些技术也可用于隐私保护检测(如登录状态检测)
5 总结
前端安全威胁持续演进,ClickJacking、MIME Sniffing和XS-Leaks代表了不同维度的攻击面:
- ClickJacking:视觉欺骗层面的攻击
- MIME Sniffing:内容类型推断层面的攻击
- XS-Leaks:侧信道信息推断层面的攻击
防御需要多层次策略,包括正确的HTTP头设置、资源隔离策略、Cookie保护措施以及服务器端验证机制。持续关注浏览器安全特性更新和新的攻击技术至关重要。