[epiphany/pgriffis/web-extension/cors] WebExtensions: Bypass CORS for host permissions
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/pgriffis/web-extension/cors] WebExtensions: Bypass CORS for host permissions
- Date: Sat, 4 Jun 2022 01:13:14 +0000 (UTC)
commit f34437c7af2e306d016cae68b991a4823b81b77b
Author: Patrick Griffis <pgriffis igalia com>
Date: Fri Jun 3 16:29:46 2022 -0500
WebExtensions: Bypass CORS for host permissions
As per the documentation host permissions grant you access to use
fetch and xhr without CORS restrictions:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#host_permissions
Part-of: <https://gitlab.gnome.org/GNOME/epiphany/-/merge_requests/1130>
src/webextension/api/tabs.c | 8 ++---
src/webextension/ephy-web-extension-manager.c | 2 ++
src/webextension/ephy-web-extension.c | 51 ++++++++++++++++++++++-----
src/webextension/ephy-web-extension.h | 4 ++-
4 files changed, 52 insertions(+), 13 deletions(-)
---
diff --git a/src/webextension/api/tabs.c b/src/webextension/api/tabs.c
index 112dd4f46..7d857e607 100644
--- a/src/webextension/api/tabs.c
+++ b/src/webextension/api/tabs.c
@@ -309,7 +309,7 @@ tabs_handler_insert_css (EphyWebExtension *self,
return NULL;
}
- if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
+ if (!ephy_web_extension_has_host_or_active_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_PERMISSION_DENIED, "Permission
Denied");
return NULL;
}
@@ -364,7 +364,7 @@ tabs_handler_remove_css (EphyWebExtension *self,
return NULL;
}
- if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
+ if (!ephy_web_extension_has_host_or_active_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_PERMISSION_DENIED, "Permission
Denied");
return NULL;
}
@@ -482,7 +482,7 @@ tabs_handler_execute_script (EphyWebExtension *self,
target_web_view = get_web_view_for_tab_id (shell, jsc_value_to_int32 (tab_id_value), NULL);
if (code && target_web_view) {
- if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
+ if (!ephy_web_extension_has_host_or_active_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
g_task_return_new_error (task, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_PERMISSION_DENIED, "Permission
Denied");
return;
}
@@ -528,7 +528,7 @@ tabs_handler_send_message (EphyWebExtension *self,
target_web_view = get_web_view_for_tab_id (shell, jsc_value_to_int32 (tab_id_value), NULL);
if (target_web_view) {
- if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
+ if (!ephy_web_extension_has_host_or_active_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_PERMISSION_DENIED, "Permission
Denied");
return NULL;
}
diff --git a/src/webextension/ephy-web-extension-manager.c b/src/webextension/ephy-web-extension-manager.c
index a61ec724d..27bf3db82 100644
--- a/src/webextension/ephy-web-extension-manager.c
+++ b/src/webextension/ephy-web-extension-manager.c
@@ -769,6 +769,8 @@ create_web_extensions_webview (EphyWebExtension *web_extension)
"related-view", ephy_web_extension_manager_get_background_web_view (manager,
web_extension),
NULL);
+ webkit_web_view_set_cors_allowlist (WEBKIT_WEB_VIEW (web_view), ephy_web_extension_get_host_permissions
(web_extension));
+
settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (web_view));
webkit_settings_set_enable_write_console_messages_to_stdout (settings, TRUE);
diff --git a/src/webextension/ephy-web-extension.c b/src/webextension/ephy-web-extension.c
index 189279737..b99caf6a3 100644
--- a/src/webextension/ephy-web-extension.c
+++ b/src/webextension/ephy-web-extension.c
@@ -107,6 +107,7 @@ struct _EphyWebExtension {
GList *resources;
GList *custom_css;
GPtrArray *permissions;
+ GPtrArray *host_permissions;
GCancellable *cancellable;
char *local_storage_path;
JsonNode *local_storage;
@@ -116,6 +117,8 @@ G_DEFINE_QUARK (web - extension - error - quark, web_extension_error)
G_DEFINE_TYPE (EphyWebExtension, ephy_web_extension, G_TYPE_OBJECT)
+static gboolean is_supported_scheme (const char *scheme);
+
gboolean
ephy_web_extension_has_resource (EphyWebExtension *self,
const char *name)
@@ -714,8 +717,24 @@ web_extension_add_permission (JsonArray *array,
gpointer user_data)
{
EphyWebExtension *self = EPHY_WEB_EXTENSION (user_data);
+ const char *permission = json_node_get_string (element_node);
+
+ if (strstr (permission, "://") != NULL) {
+ if (!is_supported_scheme (g_uri_peek_scheme (permission))) {
+ g_warning ("Unsupported host permission: %s", permission);
+ return;
+ }
+ g_ptr_array_insert (self->host_permissions, 0, g_strdup (permission));
+ return;
+ }
+
+ if (strcmp (permission, "<all_urls>") == 0) {
+ g_ptr_array_insert (self->host_permissions, 0, g_strdup ("http://*/*"));
+ g_ptr_array_insert (self->host_permissions, 0, g_strdup ("https://*/*"));
+ return;
+ }
- g_ptr_array_add (self->permissions, g_strdup (json_node_get_string (element_node)));
+ g_ptr_array_add (self->permissions, g_strdup (permission));
}
static void
@@ -747,6 +766,7 @@ ephy_web_extension_dispose (GObject *object)
g_clear_pointer (&self->background, web_extension_background_free);
g_clear_pointer (&self->options_ui, web_extension_options_ui_free);
g_clear_pointer (&self->permissions, g_ptr_array_unref);
+ g_clear_pointer (&self->host_permissions, g_ptr_array_unref);
g_clear_pointer (&self->local_storage, json_node_unref);
g_clear_pointer (&self->page_action, web_extension_page_action_free);
@@ -771,10 +791,13 @@ ephy_web_extension_init (EphyWebExtension *self)
{
self->page_action_map = g_hash_table_new (NULL, NULL);
self->permissions = g_ptr_array_new_full (1, g_free);
+ self->host_permissions = g_ptr_array_new_full (2, g_free);
self->guid = g_uuid_string_random ();
- g_ptr_array_add (self->permissions, g_strdup_printf ("ephy-webextension://%s/*", self->guid));
+ g_ptr_array_add (self->host_permissions, g_strdup_printf ("ephy-webextension://%s/*", self->guid));
+ /* This has to be NULL terminated as we pass it to webkit_web_view_set_cors_allowlist() directly. */
+ g_ptr_array_add (self->host_permissions, NULL);
}
static EphyWebExtension *
@@ -1236,6 +1259,13 @@ ephy_web_extension_get_permissions (EphyWebExtension *self)
return self->permissions;
}
+const char * const *
+ephy_web_extension_get_host_permissions (EphyWebExtension *self)
+{
+ g_assert (self->host_permissions->pdata[self->host_permissions->len - 1] == NULL);
+ return (const char * const *)self->host_permissions->pdata;
+}
+
static gboolean
is_supported_scheme (const char *scheme)
{
@@ -1368,9 +1398,6 @@ ephy_web_extension_has_permission_internal (EphyWebExtension *self,
{
EphyWebView *active_web_view = ephy_shell_get_active_web_view (ephy_shell_get_default ());
gboolean is_active_tab = active_web_view == web_view;
- GUri *host = g_uri_parse (ephy_web_view_get_address (web_view), G_URI_FLAGS_ENCODED_PATH |
G_URI_FLAGS_ENCODED_QUERY | G_URI_FLAGS_SCHEME_NORMALIZE, NULL);
-
- g_assert (host);
/* https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns */
@@ -1382,6 +1409,14 @@ ephy_web_extension_has_permission_internal (EphyWebExtension *self,
if (allow_tabs && strcmp (permission, "tabs") == 0)
return TRUE;
+ }
+
+ /* Note this one is NULL terminated. */
+ for (guint i = 0; i < self->host_permissions->len - 1; i++) {
+ GUri *host = g_uri_parse (ephy_web_view_get_address (web_view), G_URI_FLAGS_ENCODED_PATH |
G_URI_FLAGS_ENCODED_QUERY | G_URI_FLAGS_SCHEME_NORMALIZE, NULL);
+ const char *permission = g_ptr_array_index (self->permissions, i);
+
+ g_assert (host);
if (permission_matches_uri (permission, host))
return TRUE;
@@ -1391,9 +1426,9 @@ ephy_web_extension_has_permission_internal (EphyWebExtension *self,
}
gboolean
-ephy_web_extension_has_host_permission (EphyWebExtension *self,
- EphyWebView *web_view,
- gboolean is_user_interaction)
+ephy_web_extension_has_host_or_active_permission (EphyWebExtension *self,
+ EphyWebView *web_view,
+ gboolean is_user_interaction)
{
return ephy_web_extension_has_permission_internal (self, web_view, is_user_interaction, FALSE);
}
diff --git a/src/webextension/ephy-web-extension.h b/src/webextension/ephy-web-extension.h
index c20ab964c..40d2ba11f 100644
--- a/src/webextension/ephy-web-extension.h
+++ b/src/webextension/ephy-web-extension.h
@@ -152,13 +152,15 @@ gboolean ephy_web_extension_has_tab_or_host_permission (EphyW
EphyWebView *web_view,
gboolean
is_user_interaction);
-gboolean ephy_web_extension_has_host_permission (EphyWebExtension *self,
+gboolean ephy_web_extension_has_host_or_active_permission (EphyWebExtension *self,
EphyWebView *web_view,
gboolean
is_user_interaction);
gboolean ephy_web_extension_has_permission (EphyWebExtension *self,
const char *permission);
+const char * const *ephy_web_extension_get_host_permissions (EphyWebExtension *self);
+
JsonNode *ephy_web_extension_get_local_storage (EphyWebExtension *self);
void ephy_web_extension_save_local_storage (EphyWebExtension *self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]