Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn about/prevent multiple direct remote connections #20834

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pkg/static/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
<span id="banner-message" class="pf-v5-c-alert__title"></span>
</div>

<div id="multihost-warning" class="pf-v5-c-alert pf-m-info pf-m-inline dialog-error" aria-label="inline danger alert" hidden="true">
<svg fill="currentColor" viewBox="0 0 448 512" aria-hidden="true">
<path d="M224 512c35.32 0 63.97-28.65 63.97-64H160.03c0 35.35 28.65 64 63.97 64zm215.39-149.71c-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84C118.56 68.1 64.08 130.3 64.08 208c0 102.3-36.15 133.53-55.47 154.29-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h383.8c19.12 0 32-15.6 32.1-32 .05-7.55-2.61-15.27-8.61-21.71z" />
</svg>
<p id="multihost-message" class="pf-v5-c-alert__title"></p>
<button id="multihost-get-me-there" class="pf-v5-c-button">Go there</button>
</div>

<span id="badge"></span>

<div class="container" id="main">
Expand Down
31 changes: 31 additions & 0 deletions pkg/static/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,33 @@ import "./login.scss";
event.stopPropagation();
}

function deal_with_multihost() {
// If we are currently logged in to some machine, but still
// end up on the login page, we are about to load resources
// from two machines into the same browser origin.

const logged_into = environment["logged-into"];
const cur_machine = logged_into.length > 0 ? logged_into[0] : null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.


function redirect_to_current_machine() {
if (cur_machine === ".")
login_reload("/");
Comment on lines +349 to +351
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 added lines are not executed by any test.

else
login_reload("/=" + cur_machine);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.

}

if (cur_machine) {
if (!environment.page.allow_multi_host)
redirect_to_current_machine();
Comment on lines +356 to +358
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 added lines are not executed by any test.

else {
id("multihost-message").textContent = format(_("You are already connected to '$0' in this browser session. Connecting to other hosts will allow them to execute arbitrary code on each other. Please be careful."),
cur_machine == "." ? "localhost" : cur_machine);
id("multihost-get-me-there").addEventListener("click", redirect_to_current_machine);
show('#multihost-warning');
Comment on lines +360 to +363
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 4 added lines are not executed by any test.

}
}
}

function boot() {
window.onload = null;

Expand All @@ -348,6 +375,8 @@ import "./login.scss";
document.documentElement.dir = window.cockpit_po[""]["language-direction"];
}

deal_with_multihost();

setup_path_globals(window.location.pathname);

/* Determine if we are nested or not, and switch styles */
Expand Down Expand Up @@ -948,6 +977,8 @@ import "./login.scss";
}

function login_reload (wanted) {
console.log("RELOAD", wanted);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.


// Force a reload if not triggered below
// because only the hash part of the url
// changed
Expand Down
4 changes: 2 additions & 2 deletions pkg/static/login.scss
Original file line number Diff line number Diff line change
Expand Up @@ -354,14 +354,14 @@ label.checkbox {
display: none;
}

.login-pf #banner {
.login-pf #banner, .login-pf #multihost-warning {
margin-block: 1rem 0.5rem;
margin-inline: 0;
grid-area: banner;
inline-size: 100%;
}

#banner-message {
#banner-message, #multihost-message {
white-space: pre-wrap;
max-block-size: 12em;
overflow: auto;
Expand Down
10 changes: 10 additions & 0 deletions src/ws/cockpitauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1706,3 +1706,13 @@ cockpit_auth_empty_cookie_value (const gchar *path, gboolean secure)

return cookie_line;
}

gchar *
cockpit_auth_cookie_name (const gchar *path)
{
gchar *application = cockpit_auth_parse_application (path, NULL);
gchar *cookie = application_cookie_name (application);
g_free (application);

return cookie;
}
2 changes: 2 additions & 0 deletions src/ws/cockpitauth.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ gchar * cockpit_auth_parse_application (const gchar *path,
gchar * cockpit_auth_empty_cookie_value (const gchar *path,
gboolean secure);

gchar * cockpit_auth_cookie_name (const gchar *path);

G_END_DECLS

#endif
46 changes: 44 additions & 2 deletions src/ws/cockpithandlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,48 @@ add_page_to_environment (JsonObject *object,
json_object_set_object_member (object, "page", page);
}

static void
add_logged_into_to_environment (JsonObject *object,
const gchar *path,
GHashTable *request_headers)
{
gchar *h = g_hash_table_lookup (request_headers, "Cookie");
if (!h)
return;

g_autofree gchar *self_cookie = cockpit_auth_cookie_name (path);

JsonArray *logged_into = json_array_new ();

while (*h) {
const gchar *start = h;
while (*h && *h != '=')
h++;
const gchar *equal = h;
while (*h && *h != ';')
h++;
if (*h)
h++;
while (*h && *h == ' ')
h++;

if (g_str_has_prefix (equal, "=deleted"))
continue;

g_autofree gchar *name = g_strndup (start, equal - start);
if (g_str_equal (name, self_cookie))
;
else if (g_str_equal (name, "cockpit"))
json_array_add_string_element(logged_into, ".");
else if (g_str_has_prefix (name, "machine-cockpit+"))
json_array_add_string_element(logged_into, name + strlen("machine-cockpit+"));
}

json_object_set_array_member (object, "logged-into", logged_into);
}

static GBytes *
build_environment (GHashTable *os_release)
build_environment (GHashTable *os_release, const gchar *path, GHashTable *request_headers)
{
/*
* We don't include entirety of os-release into the
Expand Down Expand Up @@ -310,6 +350,7 @@ build_environment (GHashTable *os_release)
json_object_set_boolean_member (object, "is_cockpit_client", is_cockpit_client);

add_page_to_environment (object, is_cockpit_client);
add_logged_into_to_environment (object, path, request_headers);

hostname = g_malloc0 (HOST_NAME_MAX + 1);
gethostname (hostname, HOST_NAME_MAX);
Expand Down Expand Up @@ -386,7 +427,7 @@ send_login_html (CockpitWebResponse *response,
GBytes *po_bytes;
CockpitWebFilter *filter3 = NULL;

environment = build_environment (ws->os_release);
environment = build_environment (ws->os_release, path, headers);
filter = cockpit_web_inject_new (marker, environment, 1);
g_bytes_unref (environment);
cockpit_web_response_add_filter (response, filter);
Expand Down Expand Up @@ -455,6 +496,7 @@ send_login_html (CockpitWebResponse *response,
"Content-Security-Policy", content_security_policy,
"Set-Cookie", cookie_line,
NULL);
cockpit_web_response_set_cache_type (response, COCKPIT_WEB_RESPONSE_NO_CACHE);
if (cockpit_web_response_queue (response, bytes))
cockpit_web_response_complete (response);

Expand Down
Loading