Clickjacking (点击劫持) 攻击的原理和防御措施 (X-Frame-Options, Content-Security-Policy: frame-ancestors)。

同学们,早上好!我是老码农,今天咱们来聊聊一个听起来有点像好莱坞大片的网络安全问题——Clickjacking,中文名叫“点击劫持”。

啥是点击劫持?简单来说,就是坏人把你带到一个看起来无害的网站上,然后在你不知不觉中,让你点击了另一个网站上的按钮,做了你原本不想做的事情。是不是有点像电影里的催眠术?

一、点击劫持的“障眼法”

想象一下,你在网上开开心心地浏览猫片,突然出现一个弹窗,说“恭喜你获得免费iPhone!点击领取!” 你心想,天上掉馅饼了?赶紧点一下。

但实际上,这个“免费iPhone”的弹窗背后,可能隐藏着一个你正在登录的银行网站的“转账”按钮。坏人通过一些技术手段,把银行网站的转账按钮透明地覆盖在了“领取iPhone”的按钮上。你以为点击了“领取iPhone”,实际上却点击了“转账”,把钱转到了坏人的账户里。

这就是点击劫持的精髓:欺骗用户点击隐藏的元素,执行恶意操作

它主要利用了 HTML 中的 <iframe> 标签。 <iframe> 允许在一个网页中嵌入另一个网页。坏人就可以把目标网站嵌入到自己的网站里,然后通过 CSS 样式,把目标网站隐藏起来或者透明化。

举个例子:

<!DOCTYPE html>
<html>
<head>
<title>Clickjacking Example</title>
<style>
  #evilFrame {
    position: relative;
    width: 300px;
    height: 200px;
    opacity: 0.0001; /* 几乎完全透明 */
    z-index: 2; /* 放在猫片上面 */
  }

  #catPicture {
    position: relative;
    width: 300px;
    height: 200px;
    z-index: 1; /* 放在 evilFrame 下面 */
  }
</style>
</head>
<body>

<img id="catPicture" src="cat.jpg" alt="可爱的猫咪" />

<iframe id="evilFrame" src="https://your-bank.com/transfer.html"></iframe>

<p>看起来没什么问题,对吧?</p>

</body>
</html>

在这个例子中:

  • cat.jpg 是一张猫片,用来吸引你的注意力。
  • https://your-bank.com/transfer.html 是你的银行网站的转账页面(假设存在)。
  • evilFrame 这个 <iframe> 元素,用 CSS 设置了 opacity: 0.0001;,几乎完全透明,并且用 z-index 属性把它放在了猫片上面。

当你点击猫片的时候,实际上点击的是 evilFrame 里的转账按钮!

二、点击劫持的常见套路

点击劫持的套路五花八门,但万变不离其宗,都是利用 <iframe> 标签和 CSS 样式来欺骗用户。常见的套路包括:

  • Like劫持: 伪装成社交网站的“喜欢”按钮,诱导用户点击,实际上是让用户关注了某个恶意账号或者发布了恶意内容。
  • Flash劫持: 利用 Flash 的透明窗口,覆盖在目标网站上,诱导用户点击 Flash 窗口,实际上是点击了目标网站上的按钮。
  • Cursor劫持: 改变鼠标指针的位置,让用户以为点击的是某个按钮,实际上点击的是另一个按钮。

三、防御点击劫持的“金钟罩”

要防御点击劫持,就像练武功一样,需要内外兼修。

1. X-Frame-Options:简单粗暴但有效

X-Frame-Options 是一个 HTTP 响应头,用来告诉浏览器是否允许当前页面被嵌入到 <iframe> 中。它有三个可选值:

  • DENY: 完全禁止当前页面被嵌入到 <iframe> 中。
  • SAMEORIGIN: 只允许同源域名下的页面嵌入当前页面。
  • ALLOW-FROM uri: 允许指定域名下的页面嵌入当前页面(不推荐使用,浏览器支持不一致)。

举个例子,如果你的银行网站设置了 X-Frame-Options: DENY,那么坏人就无法把你的银行网站嵌入到他的恶意网站里了。

如何设置 X-Frame-Options?

  • Apache:.htaccess 文件中添加:
    Header always set X-Frame-Options "DENY"
  • Nginx:nginx.conf 文件中添加:
    add_header X-Frame-Options "DENY";
  • Java (Servlet):
    response.setHeader("X-Frame-Options", "DENY");
  • PHP:
    header('X-Frame-Options: DENY');
  • Node.js (Express):
    app.use(function(req, res, next) {
      res.setHeader('X-Frame-Options', 'DENY');
      next();
    });

X-Frame-Options 的优点是简单易用,兼容性好。但缺点也很明显:只能设置一个域名,无法灵活地控制哪些域名可以嵌入当前页面。

2. Content-Security-Policy (CSP):更强大的“护身符”

Content-Security-Policy (CSP) 是一个更强大的 HTTP 响应头,可以控制浏览器可以加载哪些资源,包括是否允许嵌入到 <iframe> 中。

CSP 使用 frame-ancestors 指令来控制哪些域名可以嵌入当前页面。

举个例子:

Content-Security-Policy: frame-ancestors 'self' https://example.com;

这个 CSP 策略表示:

  • 'self':允许同源域名下的页面嵌入当前页面。
  • https://example.com:允许 https://example.com 域名下的页面嵌入当前页面。

如何设置 CSP?

  • Apache:.htaccess 文件中添加:
    Header always set Content-Security-Policy "frame-ancestors 'self' https://example.com;"
  • Nginx:nginx.conf 文件中添加:
    add_header Content-Security-Policy "frame-ancestors 'self' https://example.com;";
  • Java (Servlet):
    response.setHeader("Content-Security-Policy", "frame-ancestors 'self' https://example.com");
  • PHP:
    header("Content-Security-Policy: frame-ancestors 'self' https://example.com");
  • Node.js (Express):
    app.use(function(req, res, next) {
      res.setHeader('Content-Security-Policy', "frame-ancestors 'self' https://example.com");
      next();
    });

CSP 的优点是功能强大,可以灵活地控制哪些域名可以嵌入当前页面,还可以控制其他资源的加载。缺点是配置复杂,兼容性不如 X-Frame-Options

CSP 的更多用法

除了 frame-ancestors 指令,CSP 还有很多其他的指令,可以用来控制各种资源的加载:

指令 描述
default-src 定义了其他指令未定义时默认的资源加载策略。
script-src 定义了允许加载的 JavaScript 资源的来源。
style-src 定义了允许加载的 CSS 资源的来源。
img-src 定义了允许加载的图片资源的来源。
connect-src 定义了允许建立的 HTTP 连接的来源(例如,AJAX 请求、WebSocket)。
font-src 定义了允许加载的字体资源的来源。
media-src 定义了允许加载的媒体资源的来源(例如,视频、音频)。
object-src 定义了允许加载的插件资源的来源(例如,Flash)。
frame-src 已经过时,请使用 frame-ancestors
child-src 定义了允许加载的 Web Worker 和嵌套的浏览上下文(例如,<iframe>)的来源。
form-action 定义了允许提交表单的 URL。
upgrade-insecure-requests 指示浏览器将所有 HTTP URL 视为 HTTPS,并将所有不安全的请求转换为安全请求。这有助于防止混合内容错误,并提高网站的安全性。
block-all-mixed-content 确保浏览器不会加载任何使用 HTTP 的资源。这有助于避免中间人攻击,并确保网站的所有资源都通过加密连接加载。

例如,你可以使用以下 CSP 策略来限制 JavaScript 只能从同源域名加载:

Content-Security-Policy: script-src 'self';

3. JavaScript 防御:最后的“防线”

即使设置了 X-Frame-Options 或 CSP,仍然有一些特殊情况可能导致点击劫持攻击成功。例如,某些老旧浏览器可能不支持这些 HTTP 响应头。

因此,我们可以在客户端使用 JavaScript 来进行额外的防御。

JavaScript 防御的原理:

通过 JavaScript 代码,检测当前页面是否被嵌入到 <iframe> 中。如果被嵌入,就采取一些措施,例如:

  • 隐藏页面: 直接把页面隐藏起来,让用户无法看到。
  • 重定向页面: 把页面重定向到当前域名的顶级页面,防止被恶意网站利用。

JavaScript 防御的代码示例:

if (window.top !== window.self) {
  // 页面被嵌入到 <iframe> 中
  window.top.location.href = window.self.location.href; // 重定向到顶级页面
  // 或者
  document.body.style.display = 'none'; // 隐藏页面
}

这段代码的原理很简单:

  • window.top 指的是最顶层的窗口对象。
  • window.self 指的是当前窗口对象。

如果当前页面没有被嵌入到 <iframe> 中,那么 window.topwindow.self 指向的是同一个对象。如果当前页面被嵌入到 <iframe> 中,那么 window.top 指的是包含 <iframe> 的页面的窗口对象,而 window.self 指的是 <iframe> 内部的页面的窗口对象。

JavaScript 防御的注意事项:

  • 兼容性: 确保 JavaScript 代码在各种浏览器上都能正常运行。
  • 性能: 尽量避免使用过于复杂的 JavaScript 代码,以免影响页面性能。
  • 误判: 有些正常情况下也可能出现 window.top !== window.self 的情况,例如,页面被嵌入到 Chrome 扩展程序的 <iframe> 中。因此,需要谨慎判断,避免误判。

四、总结:内外兼修,防患于未然

防御点击劫持,需要从服务器端和客户端两方面入手,内外兼修。

| 防御措施 | 优点 | 缺点 | 适用场景 |
| ——————- | ——————————————————————- | ————————————————————————————————– | ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————</

X-Frame-

X-Frame-Options:

3.

|
|作用: X-Frame-Options HTTP 响应标头允许网站指示浏览器是否允许页面呈现在 <frame><iframe> 或其他外部框架中。使用它可以防止点击劫持式攻击,攻击者会将您的页面嵌入到他们自己的网站中,以诱骗用户执行某些操作。 | 简单,易配置,对代码无侵入性。 | 不够灵活,只能粗粒度设置,无法满足复杂场景需求。 | 站点需要防止所有或者来自特定站点嵌入的场景. |
|配置:在服务器配置文件中添加,例如 nginx.conf.htaccess。|
|常见配置值: DENY: 完全禁止任何站点嵌入。 SAMEORIGIN: 只允许同源站点嵌入。 ALLOW-FROM uri: 允许指定站点嵌入(不推荐,存在兼容性问题)。 |

1. Content-Security-Policy (CSP):

作用: CSP 是一种更全面的安全策略,可以控制浏览器允许加载的资源来源。通过 frame-ancestors 指令,可以精确控制哪些站点可以嵌入当前页面。
优点: 功能强大,灵活性高,可以进行细粒度的权限控制。
缺点: 配置复杂,学习成本高。
适用场景: 站点需要更精细的权限控制,例如允许特定站点嵌入,或者需要控制其他资源加载策略。
配置: 在服务器配置文件中添加,例如 nginx.conf.htaccess
常见配置值: frame-ancestors 'self' https://example.com; 允许同源站点和 https://example.com 嵌入。

2. JavaScript 防御:

作用: 在客户端使用 JavaScript 代码检测页面是否被嵌入到 iframe 中,如果被嵌入,则采取措施阻止攻击。
优点: 可以作为额外的安全保障,防止 X-Frame-Options 或 CSP 配置错误或失效。
缺点: 依赖客户端 JavaScript 代码执行,可能被绕过,且可能存在兼容性问题。
适用场景: 作为额外的防御手段,增强站点的安全性。
配置: 在页面中添加 JavaScript 代码,例如:

if (window.top !== window.self) {
    window.top.location.href = window.self.location.href;
}

最佳实践:

  • 优先使用 CSP: CSP 提供了更强大和灵活的防御能力,是首选的防御手段。
  • 配置 X-Frame-Options 作为备选: 对于不支持 CSP 的浏览器,X-Frame-Options 可以提供基本的防御。
  • 使用 JavaScript 代码作为额外的保障: 在客户端使用 JavaScript 代码检测和阻止点击劫持攻击,提高站点的安全性。

记住,没有绝对安全的系统,只有不断加强防御,才能有效地保护我们的网站和用户免受点击劫持的威胁。

好了,今天的讲座就到这里。大家有什么问题可以提问。希望大家以后也能像保护自己的眼睛一样,保护好自己的网络安全!谢谢大家!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注