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

admin
Wed, 23 Jul 2025 10:58:26 +0000
Javascript, clickjacking, frame, options

同学们，早上好！我是老码农，今天咱们来聊聊一个听起来有点像好莱坞大片的网络安全问题——Clickjacking，中文名叫“点击劫持”。 啥是点击劫持？简单来说，就是坏人把你带到一个看起来无害的网站上，然后在你不知不觉中，让你点击了另一个网站上的按钮，做了你原本不想做的事情。是不是有点像电影里的催眠术？ 一、点击劫持的“障眼法” 想象一下，你在网上开开心心地浏览猫片，突然出现一个弹窗，说“恭喜你获得免费iPhone！点击领取！” 你心想，天上掉馅饼了？赶紧点一下。 但实际上，这个“免费iPhone”的弹窗背后，可能隐藏着一个你正在登录的银行网站的“转账”按钮。坏人通过一些技术手段，把银行网站的转账按钮透明地覆盖在了“领取iPhone”的按钮上。你以为点击了“领取iPhone”，实际上却点击了“转账”，把钱转到了坏人的账户里。 这就是点击劫持的精髓：欺骗用户点击隐藏的元素，执行恶意操作。 它主要利用了 HTML 中的 标签。 允许在一个网页中嵌入另一个网页。坏人就可以把目标网站嵌入到自己的网站里，然后通过 CSS 样式，把目标网站 …

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

The post Clickjacking (点击劫持) 攻击的原理和防御措施 (X-Frame-Options, Content-Security-Policy: frame-ancestors)。 first appeared on 智猿学院-前后端，数据库，人工智能，云计算等领域前沿技术讲座.

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

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

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

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

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

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

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

举个例子：




Clickjacking Example

  #evilFrame {
    position: relative;
    width: 300px;
    height: 200px;
    opacity: 0.0001; /* 几乎完全透明 */
    z-index: 2; /* 放在猫片上面 */
  }

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








看起来没什么问题，对吧？




在这个例子中：

cat.jpg 是一张猫片，用来吸引你的注意力。

https://your-bank.com/transfer.html 是你的银行网站的转账页面（假设存在）。

evilFrame 这个 元素，用 CSS 设置了 opacity: 0.0001;，几乎完全透明，并且用 z-index 属性把它放在了猫片上面。

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

二、点击劫持的常见套路

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

Like劫持： 伪装成社交网站的“喜欢”按钮，诱导用户点击，实际上是让用户关注了某个恶意账号或者发布了恶意内容。

Flash劫持： 利用 Flash 的透明窗口，覆盖在目标网站上，诱导用户点击 Flash 窗口，实际上是点击了目标网站上的按钮。

Cursor劫持： 改变鼠标指针的位置，让用户以为点击的是某个按钮，实际上点击的是另一个按钮。

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

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

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

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

DENY： 完全禁止当前页面被嵌入到 中。

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 响应头，可以控制浏览器可以加载哪些资源，包括是否允许嵌入到 中。

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 和嵌套的浏览上下文（例如， ）的来源。
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 代码，检测当前页面是否被嵌入到 中。如果被嵌入，就采取一些措施，例如：

隐藏页面： 直接把页面隐藏起来，让用户无法看到。

重定向页面： 把页面重定向到当前域名的顶级页面，防止被恶意网站利用。

JavaScript 防御的代码示例：

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

这段代码的原理很简单：

window.top 指的是最顶层的窗口对象。

window.self 指的是当前窗口对象。

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

JavaScript 防御的注意事项：

兼容性： 确保 JavaScript 代码在各种浏览器上都能正常运行。

性能： 尽量避免使用过于复杂的 JavaScript 代码，以免影响页面性能。

误判： 有些正常情况下也可能出现 window.top !== window.self 的情况，例如，页面被嵌入到 Chrome 扩展程序的 中。因此，需要谨慎判断，避免误判。

四、总结：内外兼修，防患于未然

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

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

X-Frame-

X-Frame-Options：

3.

|
|作用： X-Frame-Options HTTP 响应标头允许网站指示浏览器是否允许页面呈现在 、 或其他外部框架中。使用它可以防止点击劫持式攻击，攻击者会将您的页面嵌入到他们自己的网站中，以诱骗用户执行某些操作。 | 简单，易配置，对代码无侵入性。 | 不够灵活，只能粗粒度设置，无法满足复杂场景需求。 | 站点需要防止所有或者来自特定站点嵌入的场景. |
|配置：在服务器配置文件中添加，例如 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 代码检测和阻止点击劫持攻击，提高站点的安全性。

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

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