CSRF Token防护下的Basic Clickjacking攻击原理与防御实战

1次阅读
没有评论

共计 2124 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

攻击原理:透明 iframe 的致命组合拳

当 CSRF Token 遇上 Clickjacking,就像防盗门遇到了隐身术。攻击者会构造一个精心设计的透明 iframe 层:

CSRF Token 防护下的 Basic Clickjacking 攻击原理与防御实战

<!-- 恶意网站代码 -->
<style>
  iframe {
    opacity: 0.01;
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: 999;
  }
  button {
    /* 诱骗按钮与目标按钮重合 */
    position: absolute;
    left: 100px;
    top: 200px;
  }
</style>

<button> 点击抽奖 </button>
<iframe src="https://victim.com/transfer?amount=5000"></iframe>
  1. 攻击流程
  2. 用户登录正常网站,获取有效 CSRF Token
  3. 访问恶意页面时,透明 iframe 加载真实网站表单
  4. 用户点击伪装的抽奖按钮,实际触发 iframe 内的转账操作
  5. 由于请求携带合法 Token,服务器认为是合法操作

  6. 为何 Token 防护失效

  7. Token 验证机制依然正常工作
  8. 但用户是在不知情的情况下「自愿」触发了操作
  9. 这相当于攻击者「借刀杀人」

防御方案三国杀

方案 优点 缺点 移动端兼容性
X-Frame-Options 简单粗暴,IE8+ 支持 不能细粒度控制 iOS 全支持 /Android4.4+
CSP frame-ancestors 支持白名单,现代标准 旧浏览器需降级处理 iOS13+/Android4.4+
JavaScript 断帧脚本 无兼容性问题 可被 CSS 或 XSS 绕过 全支持但不可靠

双端防御代码实战

Node.js Express 版

const helmet = require('helmet');

app.use(helmet.frameguard({ action: 'deny'})); // X-Frame-Options
app.use(helmet.contentSecurityPolicy({
  directives: {frameAncestors: ["'none'"], // CSP 第 2 层防护
    defaultSrc: ["'self'"]     // 顺带加强其他 CSP 规则
  }
}));

// 自定义中间件处理旧浏览器
app.use((req, res, next) => {
  // 针对不支持 CSP 的 UA 降级处理
  const isLegacyBrowser = /MSIE|Trident/.test(req.headers['user-agent']);
  if (isLegacyBrowser) {res.setHeader('X-Frame-Options', 'DENY');
  }
  next();});

Spring Boot 版

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .headers()
        .frameOptions().deny() // 1. 先设置 X -Frame-Options
        .and()
      .contentSecurityPolicy("frame-ancestors'none';"); // 2. CSP 补刀

    // 针对 API 特殊处理
    http.antMatcher("/api/**")
      .headers().addHeaderWriter(new StaticHeadersWriter("X-Content-Type-Options", "nosniff")
      );
  }
}

渗透测试四步曲

  1. Burp Suite 检测
  2. 使用 Proxy 拦截响应
  3. 修改 Response 移除防护头
  4. 通过 Repeater 测试不同 header 组合

  5. Selenium 自动化测试

    from selenium import webdriver
    
    def test_clickjacking(url):
        driver = webdriver.Chrome()
        driver.get(f"""
        <html><body>
        <iframe src="{url}" style="opacity:0.1;"></iframe>
        </body></html>""")
        try:
            driver.switch_to.frame(0)
            print("漏洞存在!")
        except:
            print("防护生效")
        driver.quit()

生产环境三大坑

  • HTTPS≠安全
    SSL 只是传输加密,与 Clickjacking 防护完全无关

  • SPA 的 CSP 陷阱
    Vue/React 等需要配置特殊 CSP 规则:

    script-src 'self' 'unsafe-inline';
    connect-src 'self' api.example.com;

  • 移动端幽灵点击
    部分移动浏览器会预加载 iframe 内容,即使未显示也需要防护

思考题

如果攻击者发现你的网站同时使用了:
1. X-Frame-Options: DENY
2. CSP: frame-ancestors ‘none’
3. 传统的 framebusting 脚本

你认为还有可能通过哪些意想不到的方式突破防御?试试在本地环境构造 PoC 验证你的猜想。

正文完
 0
评论(没有评论)