您现在的位置是:网站首页 > 浏览器缓存的安全问题文章详情

浏览器缓存的安全问题

浏览器缓存是提升网页加载速度的重要机制,但不当的缓存策略可能导致敏感信息泄露、XSS攻击扩大化或CSRF漏洞利用。缓存机制的设计缺陷或配置错误可能成为攻击者突破前端防御的入口点。

缓存中毒攻击

恶意用户通过操纵缓存内容注入攻击载荷。当服务器未严格校验响应头时,攻击者可能将恶意脚本存入CDN缓存:

GET /product?id=123 HTTP/1.1
Host: example.com

HTTP/1.1 200 OK
Cache-Control: public, max-age=3600
Content-Type: text/html

<script>stealCredentials()</script>  # 恶意内容被缓存

防御方案应包含内容校验与缓存范围控制:

location /dynamic {
    proxy_cache_bypass $http_cache_control;
    proxy_no_cache $http_pragma $http_authorization;
}

本地存储敏感数据泄露

localStorage和sessionStorage的持久化特性可能导致数据长期暴露:

// 错误示例:存储敏感令牌
localStorage.setItem('authToken', 'eyJhbGci...'); 

// 攻击者通过控制台直接获取
console.log(localStorage.getItem('authToken'));

替代方案应使用HttpOnly Cookie配合短期令牌:

fetch('/api/token', {
  credentials: 'include'  // 仅限同源请求携带Cookie
})

缓存侧信道攻击

利用浏览器缓存差异进行用户追踪。攻击者可检测资源缓存状态判断用户访问历史:

<script>
  function checkCache(url) {
    const img = new Image();
    img.onload = () => console.log('未缓存');
    img.onerror = () => console.log('已缓存');
    img.src = url + '?t=' + Date.now();
  }
  checkCache('https://victim.com/unique-page');
</script>

防御措施需统一缓存策略并添加随机参数:

Cache-Control: no-store, must-revalidate

Service Worker缓存劫持

恶意Service Worker可能拦截所有网络请求:

// 恶意sw.js
self.addEventListener('fetch', event => {
  if(event.request.url.includes('login')){
    return event.respondWith(
      fetch('/fake-login-page')
    );
  }
});

注册阶段必须验证HTTPS与作用域:

if ('serviceWorker' in navigator && location.protocol === 'https:') {
  navigator.serviceWorker.register('/sw.js', { scope: './' });
}

跨域缓存污染

共享缓存可能泄露跨域信息。当CDN未隔离用户内容时:

GET /user-data HTTP/1.1
Host: api.example.com
Origin: https://attacker.com

HTTP/1.1 200 OK
Cache-Control: public
Access-Control-Allow-Origin: *  # 错误配置

正确的CORS缓存策略应包含Vary头:

Vary: Origin, Accept-Encoding
Cache-Control: private, max-age=60

缓存时间炸弹

过长的max-age值会延长漏洞影响周期。某电商网站曾因长期缓存包含漏洞的jQuery版本导致攻击窗口持续数月:

Cache-Control: max-age=31536000  # 1年缓存

推荐采用版本化资源与协商缓存:

<script src="lib/v1.2.3/jquery.js"></script>

缓存密钥碰撞

未包含完整鉴别要素的缓存键可能导致数据混淆。某API网关曾因未将Authorization头纳入缓存键,导致不同用户获取相同缓存响应:

proxy_cache_key "$scheme$request_method$host$uri";  # 缺少头信息

完整缓存键应包含关键头字段:

proxy_cache_key "$scheme$request_method$host$uri$http_authorization";

离线应用缓存漏洞

AppCache等遗留技术可能固化恶意代码:

<!DOCTYPE html>
<html manifest="app.manifest">
<!-- 攻击者可修改manifest文件强制缓存恶意资源 -->

现代PWA应使用更安全的Cache API:

caches.open('v1').then(cache => {
  cache.addAll([
    '/styles/main.css',
    '/script/app.js'  // 明确控制缓存范围
  ]);
});

缓存与CSRF协同攻击

当敏感操作响应被缓存时,可能降低CSRF防护有效性:

GET /transfer?to=attacker&amount=10000 HTTP/1.1
HTTP/1.1 200 OK
Cache-Control: public  # 错误缓存转账页面

必须对敏感操作禁用缓存:

Cache-Control: no-store, no-cache, must-revalidate

浏览器实现差异风险

各浏览器对Cache-Control指令处理存在差异。例如某些版本浏览器会忽略no-store指令的某些变体:

Cache-Control: no-store, no-cache="set-cookie"  # 非标准指令

推荐使用严格的标准指令组合:

Cache-Control: no-store, private, max-age=0

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步