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
评论(没有评论)