143 lines
6.1 KiB
Diff
143 lines
6.1 KiB
Diff
From 25a8a5c6e47268933b9b4433a9590ccfd9c04c83 Mon Sep 17 00:00:00 2001
|
|
From: Martin Pitt <mpitt@redhat.com>
|
|
Date: Tue, 14 Sep 2021 09:02:33 +0200
|
|
Subject: [PATCH] common: Restrict frame embedding to same origin
|
|
|
|
Declare `X-Frame-Options: sameorigin` [1] so that cockpit frames can
|
|
only be embedded into pages coming from the same origin. This is similar
|
|
to setting CORP in commit 2b38b8de92f9a (which applies to `<script>`,
|
|
`<img>`, etc.).
|
|
|
|
The main use case for embedding is to run cockpit-ws behind a reverse
|
|
proxy, while also serving other pages. Cross-origin embedding is
|
|
discouraged these days to prevent "clickjacking".
|
|
|
|
Cross-origin embedding already did not work in most cases: Frames would
|
|
always just show the login page. However, this looks confusing and is
|
|
unclean. With X-Frame-Options, the browser instead shows an explanatory
|
|
error page.
|
|
|
|
Mention the same origin requirement in the embedding documentation.
|
|
|
|
Fixes #16122
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=1980688
|
|
CVE-2021-3660
|
|
|
|
[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
|
|
|
|
Conflict:NA
|
|
Reference:https://github.com/cockpit-project/cockpit/pull/16342/commits/25a8a5c6e47268933b9b4433a9590ccfd9c04c83
|
|
---
|
|
doc/guide/embedding.xml | 4 +++-
|
|
src/bridge/test-httpstream.c | 2 +-
|
|
src/bridge/test-packages.c | 3 +++
|
|
src/common/cockpitwebresponse.c | 6 ++++++
|
|
src/common/test-webresponse.c | 3 +++
|
|
src/ws/test-channelresponse.c | 3 +++
|
|
6 files changed, 19 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/doc/guide/embedding.xml b/doc/guide/embedding.xml
|
|
index 99b30dc..7fe8aa9 100644
|
|
--- a/doc/guide/embedding.xml
|
|
+++ b/doc/guide/embedding.xml
|
|
@@ -5,7 +5,9 @@
|
|
<title>Embedding and Integrating Cockpit</title>
|
|
|
|
<para>Cockpit can be embedded in other web applications either as a whole or specific
|
|
- Cockpit components can be integrated.</para>
|
|
+ Cockpit components can be integrated. Due to frame security policy restrictions,
|
|
+ this only works if Cockpit and the web application have the <emphasis>same origin</emphasis>;
|
|
+ this is commonly achieved by running both from a common reverse proxy.</para>
|
|
|
|
<section id="embedding-full">
|
|
<title>Embedding the Cockpit Interface</title>
|
|
diff --git a/src/bridge/test-httpstream.c b/src/bridge/test-httpstream.c
|
|
index 47af9ea..6844f72 100644
|
|
--- a/src/bridge/test-httpstream.c
|
|
+++ b/src/bridge/test-httpstream.c
|
|
@@ -31,7 +31,7 @@
|
|
#include <string.h>
|
|
|
|
/* JSON dict snippet for headers that are present in every request */
|
|
-#define STATIC_HEADERS "\"Cross-Origin-Resource-Policy\":\"same-origin\",\"Referrer-Policy\":\"no-referrer\",\"X-Content-Type-Options\":\"nosniff\",\"X-DNS-Prefetch-Control\":\"off\""
|
|
+#define STATIC_HEADERS "\"Cross-Origin-Resource-Policy\":\"same-origin\",\"Referrer-Policy\":\"no-referrer\",\"X-Content-Type-Options\":\"nosniff\",\"X-DNS-Prefetch-Control\":\"off\",\"X-Frame-Options\":\"sameorigin\""
|
|
|
|
static void
|
|
on_closed_set_flag (CockpitChannel *channel,
|
|
diff --git a/src/bridge/test-packages.c b/src/bridge/test-packages.c
|
|
index 769c51c..b96a3b4 100644
|
|
--- a/src/bridge/test-packages.c
|
|
+++ b/src/bridge/test-packages.c
|
|
@@ -45,6 +45,9 @@
|
|
#define CHECKSUM_RELOAD_UPDATED "0d1c0b7c6133cc7c3956197fd8a76bef68b158bd78beac75cfa80b75c36aa827"
|
|
#define CHECKSUM_CSP "25cab69451c3667cb9ed33f006fc7003c248f1029dae4a763bbadb0c4cafaf8d"
|
|
|
|
+/* JSON dict snippet for headers that are present in every request */
|
|
+#define STATIC_HEADERS "\"X-DNS-Prefetch-Control\":\"off\",\"Referrer-Policy\":\"no-referrer\",\"X-Content-Type-Options\":\"nosniff\",\"Cross-Origin-Resource-Policy\": \"same-origin\",\"X-Frame-Options\": \"sameorigin\""
|
|
+
|
|
extern const gchar **cockpit_bridge_data_dirs;
|
|
extern const gchar *cockpit_bridge_local_address;
|
|
extern gint cockpit_bridge_packages_port;
|
|
diff --git a/src/common/cockpitwebresponse.c b/src/common/cockpitwebresponse.c
|
|
index 0e757f3..ddf1911 100644
|
|
--- a/src/common/cockpitwebresponse.c
|
|
+++ b/src/common/cockpitwebresponse.c
|
|
@@ -735,6 +735,7 @@ enum {
|
|
HEADER_CACHE_CONTROL = 1 << 3,
|
|
HEADER_DNS_PREFETCH_CONTROL = 1 << 4,
|
|
HEADER_REFERRER_POLICY = 1 << 5,
|
|
+ HEADER_X_FRAME_OPTIONS = 1 << 8,
|
|
};
|
|
|
|
static GString *
|
|
@@ -773,6 +774,8 @@ append_header (GString *string,
|
|
return HEADER_DNS_PREFETCH_CONTROL;
|
|
if (g_ascii_strcasecmp ("Referrer-Policy", name) == 0)
|
|
return HEADER_REFERRER_POLICY;
|
|
+ if (g_ascii_strcasecmp ("X-Frame-Options", name) == 0)
|
|
+ return HEADER_X_FRAME_OPTIONS;
|
|
else if (g_ascii_strcasecmp ("Connection", name) == 0)
|
|
g_critical ("Don't set Connection header manually. This is a programmer error.");
|
|
return 0;
|
|
@@ -875,6 +878,9 @@ finish_headers (CockpitWebResponse *self,
|
|
g_string_append (string, "X-DNS-Prefetch-Control: off\r\n");
|
|
if ((seen & HEADER_REFERRER_POLICY) == 0)
|
|
g_string_append (string, "Referrer-Policy: no-referrer\r\n");
|
|
+ /* This is the counterpart for iframe embedding, line of defence against clickjacking */
|
|
+ if ((seen & HEADER_X_FRAME_OPTIONS) == 0)
|
|
+ g_string_append (string, "X-Frame-Options: sameorigin\r\n");
|
|
|
|
g_string_append (string, "\r\n");
|
|
return g_string_free_to_bytes (string);
|
|
diff --git a/src/common/test-webresponse.c b/src/common/test-webresponse.c
|
|
index ab59c13..a797f2b 100644
|
|
--- a/src/common/test-webresponse.c
|
|
+++ b/src/common/test-webresponse.c
|
|
@@ -34,6 +34,9 @@
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
+/* headers that are present in every request */
|
|
+#define STATIC_HEADERS "X-DNS-Prefetch-Control: off\r\nReferrer-Policy: no-referrer\r\nX-Content-Type-Options: nosniff\r\nCross-Origin-Resource-Policy: same-origin\r\nX-Frame-Options: sameorigin\r\n\r\n"
|
|
+
|
|
static gchar *srcdir;
|
|
|
|
typedef struct {
|
|
diff --git a/src/ws/test-channelresponse.c b/src/ws/test-channelresponse.c
|
|
index 86c0fff..763913b 100644
|
|
--- a/src/ws/test-channelresponse.c
|
|
+++ b/src/ws/test-channelresponse.c
|
|
@@ -51,6 +51,9 @@
|
|
|
|
#define PASSWORD "this is the password"
|
|
|
|
+/* headers that are present in every request */
|
|
+#define STATIC_HEADERS "X-Content-Type-Options: nosniff\r\nX-DNS-Prefetch-Control: off\r\nReferrer-Policy: no-referrer\r\nCross-Origin-Resource-Policy: same-origin\r\nX-Frame-Options: sameorigin\r\n"
|
|
+
|
|
typedef struct {
|
|
CockpitWebService *service;
|
|
GIOStream *io;
|
|
--
|
|
2.27.0
|
|
|