[epiphany/wip/google-safe-browsing: 19/37] web-view: Verify and inform user about URL safety
- From: Gabriel Ivașcu <gabrielivascu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/google-safe-browsing: 19/37] web-view: Verify and inform user about URL safety
- Date: Mon, 2 Oct 2017 18:53:35 +0000 (UTC)
commit 6379d9074740f2a5f5a7ffd4f7aa043087f18c1c
Author: Gabriel Ivascu <gabrielivascu gnome org>
Date: Wed Sep 20 21:32:33 2017 +0300
web-view: Verify and inform user about URL safety
embed/ephy-embed-shell.c | 34 +++++++
embed/ephy-web-view.c | 166 +++++++++++++++++++++++++++++++---
embed/ephy-web-view.h | 3 +-
lib/safe-browsing/ephy-gsb-storage.c | 8 +-
lib/safe-browsing/ephy-gsb-utils.h | 4 +
src/ephy-session.c | 2 +-
6 files changed, 197 insertions(+), 20 deletions(-)
---
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 9003701..3d913df 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -80,6 +80,7 @@ enum {
WEB_VIEW_CREATED,
PAGE_CREATED,
ALLOW_TLS_CERTIFICATE,
+ ALLOW_UNSAFE_BROWSING,
FORM_AUTH_DATA_SAVE_REQUESTED,
SENSITIVE_FORM_FOCUSED,
@@ -337,6 +338,17 @@ web_extension_tls_error_page_message_received_cb (WebKitUserContentManager *mana
}
static void
+web_extension_unsafe_browsing_error_page_message_received_cb (WebKitUserContentManager *manager,
+ WebKitJavascriptResult *message,
+ EphyEmbedShell *shell)
+{
+ guint64 page_id;
+
+ page_id = ephy_embed_utils_get_js_result_as_number (message);
+ g_signal_emit (shell, signals[ALLOW_UNSAFE_BROWSING], 0, page_id);
+}
+
+static void
web_extension_about_apps_message_received_cb (WebKitUserContentManager *manager,
WebKitJavascriptResult *message,
EphyEmbedShell *shell)
@@ -986,6 +998,12 @@ ephy_embed_shell_startup (GApplication *application)
shell);
webkit_user_content_manager_register_script_message_handler (priv->user_content,
+ "unsafeBrowsingErrorPage");
+ g_signal_connect (priv->user_content, "script-message-received::unsafeBrowsingErrorPage",
+ G_CALLBACK (web_extension_unsafe_browsing_error_page_message_received_cb),
+ shell);
+
+ webkit_user_content_manager_register_script_message_handler (priv->user_content,
"formAuthData");
g_signal_connect (priv->user_content, "script-message-received::formAuthData",
G_CALLBACK (web_extension_form_auth_data_message_received_cb),
@@ -1261,6 +1279,22 @@ ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
G_TYPE_UINT64);
/**
+ * EphyEmbedShell::allow-unsafe-browsing:
+ * @shell: the #EphyEmbedShell
+ * @page_id: the identifier of the web page
+ *
+ * Emitted when the web extension requests an exception be
+ * permitted for the unsafe browsing warning on the given page
+ */
+ signals[ALLOW_UNSAFE_BROWSING] =
+ g_signal_new ("allow-unsafe-browsing",
+ EPHY_TYPE_EMBED_SHELL,
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT64);
+
+ /**
* EphyEmbedShell::form-auth-data-save-requested:
* @shell: the #EphyEmbedShell
* @request_id: the identifier of the request
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index cff23ec..4fe67d7 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -33,6 +33,7 @@
#include "ephy-favicon-helpers.h"
#include "ephy-file-helpers.h"
#include "ephy-file-monitor.h"
+#include "ephy-gsb-utils.h"
#include "ephy-history-service.h"
#include "ephy-lib-type-builtins.h"
#include "ephy-option-menu.h"
@@ -78,6 +79,7 @@ struct _EphyWebView {
guint load_failed : 1;
guint history_frozen : 1;
guint ever_committed : 1;
+ guint bypass_gsb_verification : 1;
char *address;
char *display_address;
@@ -827,6 +829,18 @@ allow_tls_certificate_cb (EphyEmbedShell *shell,
}
static void
+allow_unsafe_browsing_cb (EphyEmbedShell *shell,
+ guint64 page_id,
+ EphyWebView *view)
+{
+ if (webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)) != page_id)
+ return;
+
+ view->bypass_gsb_verification = TRUE;
+ ephy_web_view_load_url (view, ephy_web_view_get_address (view));
+}
+
+static void
page_created_cb (EphyEmbedShell *shell,
guint64 page_id,
EphyWebExtensionProxy *web_extension,
@@ -849,6 +863,10 @@ page_created_cb (EphyEmbedShell *shell,
g_signal_connect_object (shell, "allow-tls-certificate",
G_CALLBACK (allow_tls_certificate_cb),
view, 0);
+
+ g_signal_connect_object (shell, "allow-unsafe-browsing",
+ G_CALLBACK (allow_unsafe_browsing_cb),
+ view, 0);
}
static void
@@ -1008,7 +1026,7 @@ process_crashed_cb (EphyWebView *web_view, gpointer user_data)
return;
ephy_web_view_load_error_page (web_view, ephy_web_view_get_address (web_view),
- EPHY_WEB_VIEW_ERROR_PROCESS_CRASH, NULL);
+ EPHY_WEB_VIEW_ERROR_PROCESS_CRASH, NULL, NULL);
}
static gboolean
@@ -1259,12 +1277,74 @@ new_window_cb (EphyWebView *view,
popups_manager_add_window (view, container);
}
+typedef struct {
+ EphyWebView *web_view;
+ WebKitPolicyDecision *decision;
+ char *request_uri;
+} VerifyUrlData;
+
+static inline VerifyUrlData *
+verify_url_data_new (EphyWebView *web_view,
+ WebKitPolicyDecision *decision,
+ const char *request_uri)
+{
+ VerifyUrlData *data = g_slice_new (VerifyUrlData);
+
+ data->web_view = g_object_ref (web_view);
+ data->decision = g_object_ref (decision);
+ data->request_uri = g_strdup (request_uri);
+
+ return data;
+}
+
+static inline void
+verify_url_data_free (VerifyUrlData *data)
+{
+ g_object_unref (data->web_view);
+ g_object_unref (data->decision);
+ g_free (data->request_uri);
+ g_slice_free (VerifyUrlData, data);
+}
+
+static void
+verify_url_cb (GHashTable *threats,
+ gpointer user_data)
+{
+ VerifyUrlData *data = (VerifyUrlData *)user_data;
+ EphyGSBThreatList *list;
+ GList *threat_lists;
+
+ if (g_hash_table_size (threats) == 0) {
+ webkit_policy_decision_use (data->decision);
+ goto out;
+ }
+
+ webkit_policy_decision_ignore (data->decision);
+
+ /* Very rarely there are URLs that pose multiple types of threats.
+ * However, inform the user only about the first threat type.
+ */
+ threat_lists = g_hash_table_get_keys (threats);
+ list = threat_lists->data;
+ ephy_web_view_load_error_page (data->web_view, data->request_uri,
+ EPHY_WEB_VIEW_ERROR_UNSAFE_BROWSING,
+ NULL, list->threat_type);
+
+ g_list_free (threat_lists);
+out:
+ g_hash_table_unref (threats);
+ verify_url_data_free (data);
+}
+
static gboolean
decide_policy_cb (WebKitWebView *web_view,
WebKitPolicyDecision *decision,
WebKitPolicyDecisionType decision_type,
gpointer user_data)
{
+ EphyGSBService *service;
+ WebKitNavigationPolicyDecision *navigation_decision;
+ WebKitNavigationAction *action;
WebKitResponsePolicyDecision *response_decision;
WebKitURIResponse *response;
WebKitURIRequest *request;
@@ -1273,6 +1353,30 @@ decide_policy_cb (WebKitWebView *web_view,
const char *mime_type;
const char *request_uri;
+ if (decision_type == WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION) {
+ if (!g_settings_get_boolean (EPHY_SETTINGS_WEB,
+ EPHY_PREFS_WEB_ENABLE_SAFE_BROWSING))
+ return FALSE;
+
+ if (EPHY_WEB_VIEW (web_view)->bypass_gsb_verification) {
+ EPHY_WEB_VIEW (web_view)->bypass_gsb_verification = FALSE;
+ return FALSE;
+ }
+
+ navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
+ action = webkit_navigation_policy_decision_get_navigation_action (navigation_decision);
+ request = webkit_navigation_action_get_request (action);
+ request_uri = webkit_uri_request_get_uri (request);
+
+ service = ephy_embed_shell_get_global_gsb_service (ephy_embed_shell_get_default ());
+ ephy_gsb_service_verify_url (service, request_uri, verify_url_cb,
+ verify_url_data_new (EPHY_WEB_VIEW (web_view),
+ decision, request_uri));
+
+ /* Delay decision until the safe browsing verification has completed. */
+ return TRUE;
+ }
+
if (decision_type != WEBKIT_POLICY_DECISION_TYPE_RESPONSE)
return FALSE;
@@ -2155,6 +2259,7 @@ format_tls_error_page (EphyWebView *view,
static void
format_unsafe_browsing_error_page (EphyWebView *view,
const char *origin,
+ const char *threat_type,
char **page_title,
char **message_title,
char **message_body,
@@ -2178,17 +2283,47 @@ format_unsafe_browsing_error_page (EphyWebView *view,
*message_title = g_strdup (_("Unsafe website detected!"));
formatted_origin = g_strdup_printf ("<strong>%s</strong>", origin);
- /* Error details on the unsafe browsing error page. */
- first_paragraph = g_strdup_printf (_("%s is reported to be unsafe. It might "
- "trick you by pretending to be a "
- "different website to steal your "
- "information, or it might harm "
- "your computer by installing malicious "
- "software."), /* FIXME: be more accurate */
- formatted_origin);
+ /* Error details on the unsafe browsing error page.
+ * https://developers.google.com/safe-browsing/v4/usage-limits#UserWarnings
+ */
+ if (!g_strcmp0 (threat_type, GSB_THREAT_TYPE_MALWARE)) {
+ first_paragraph = g_strdup_printf (_("Visiting %s may harm your computer. This "
+ "page appears to contain malicious code that could "
+ "be downloaded to your computer without your consent."),
+ formatted_origin);
+ *message_details = g_strdup_printf (_("You can learn more about harmful web content "
+ "including viruses and other malicious code "
+ "and how to protect your computer at %s."),
+ "<a href=\"https://www.stopbadware.org/\">"
+ "www.stopbadware.org"
+ "</a>");
+ } else if (!g_strcmp0 (threat_type, GSB_THREAT_TYPE_SOCIAL_ENGINEERING)) {
+ first_paragraph = g_strdup_printf (_("Attackers on %s may trick you into doing "
+ "something dangerous like installing software or "
+ "revealing your personal information (for example, "
+ "passwords, phone numbers, or credit cards)."),
+ formatted_origin);
+ *message_details = g_strdup_printf (_("You can find out more about social engineering "
+ "(phishing) at %s or from %s."),
+ "<a href=\"https://support.google.com/webmasters/answer/6350487\">"
+ "Social Engineering (Phishing and Deceptive Sites)"
+ "</a>",
+ "<a href=\"https://www.antiphishing.org/\">"
+ "www.antiphishing.org"
+ "</a>");
+ } else {
+ first_paragraph = g_strdup_printf (_("%s may contain harmful programs. Attackers might "
+ "attempt to trick you into installing programs that "
+ "harm your browsing experience (for example, by changing "
+ "your homepage or showing extra ads on sites you visit)."),
+ formatted_origin);
+ *message_details = g_strdup_printf (_("You can learn more about unwanted software at %s."),
+ "<a
href=\"https://www.google.com/about/unwanted-software-policy.html\">"
+ "Unwanted Software Policy"
+ "</a>");
+ }
*message_body = g_strdup_printf ("<p>%s</p>", first_paragraph);
- *message_details = g_strdup (""); /* FIXME */
/* The button on unsafe browsing error page. DO NOT ADD MNEMONICS HERE. */
*button_label = g_strdup (_("Go Back"));
@@ -2216,6 +2351,7 @@ format_unsafe_browsing_error_page (EphyWebView *view,
* @uri: uri that caused the failure
* @page: one of #EphyWebViewErrorPage
* @error: a GError to inspect, or %NULL
+ * @user_data: a pointer to additional data
*
* Loads an error page appropiate for @page in @view.
*
@@ -2224,7 +2360,8 @@ void
ephy_web_view_load_error_page (EphyWebView *view,
const char *uri,
EphyWebViewErrorPage page,
- GError *error)
+ GError *error,
+ gpointer user_data)
{
GBytes *html_file;
GString *html = g_string_new ("");
@@ -2322,6 +2459,7 @@ ephy_web_view_load_error_page (EphyWebView *view,
case EPHY_WEB_VIEW_ERROR_UNSAFE_BROWSING:
format_unsafe_browsing_error_page (view,
origin,
+ user_data,
&page_title,
&msg_title,
&msg_body,
@@ -2400,7 +2538,7 @@ load_failed_cb (WebKitWebView *web_view,
if (error->domain != WEBKIT_NETWORK_ERROR &&
error->domain != WEBKIT_POLICY_ERROR &&
error->domain != WEBKIT_PLUGIN_ERROR) {
- ephy_web_view_load_error_page (view, uri, EPHY_WEB_VIEW_ERROR_PAGE_NETWORK_ERROR, error);
+ ephy_web_view_load_error_page (view, uri, EPHY_WEB_VIEW_ERROR_PAGE_NETWORK_ERROR, error, NULL);
return TRUE;
}
@@ -2418,7 +2556,7 @@ load_failed_cb (WebKitWebView *web_view,
case WEBKIT_PLUGIN_ERROR_CANNOT_LOAD_PLUGIN:
case WEBKIT_PLUGIN_ERROR_JAVA_UNAVAILABLE:
case WEBKIT_PLUGIN_ERROR_CONNECTION_CANCELLED:
- ephy_web_view_load_error_page (view, uri, EPHY_WEB_VIEW_ERROR_PAGE_NETWORK_ERROR, error);
+ ephy_web_view_load_error_page (view, uri, EPHY_WEB_VIEW_ERROR_PAGE_NETWORK_ERROR, error, NULL);
return TRUE;
case WEBKIT_NETWORK_ERROR_CANCELLED:
{
@@ -2462,7 +2600,7 @@ load_failed_with_tls_error_cb (WebKitWebView *web_view,
view->tls_errors = errors;
view->tls_error_failing_uri = g_strdup (uri);
ephy_web_view_load_error_page (EPHY_WEB_VIEW (web_view), uri,
- EPHY_WEB_VIEW_ERROR_INVALID_TLS_CERTIFICATE, NULL);
+ EPHY_WEB_VIEW_ERROR_INVALID_TLS_CERTIFICATE, NULL, NULL);
return TRUE;
}
diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h
index f5bbdbe..49da569 100644
--- a/embed/ephy-web-view.h
+++ b/embed/ephy-web-view.h
@@ -114,7 +114,8 @@ EphyWebViewErrorPage ephy_web_view_get_error_page (EphyWebView
void ephy_web_view_load_error_page (EphyWebView *view,
const char *uri,
EphyWebViewErrorPage page,
- GError *error);
+ GError *error,
+ gpointer user_data);
void ephy_web_view_get_best_web_app_icon (EphyWebView *view,
GCancellable *cancellable,
GAsyncReadyCallback callback,
diff --git a/lib/safe-browsing/ephy-gsb-storage.c b/lib/safe-browsing/ephy-gsb-storage.c
index 6f27610..0abb4ec 100644
--- a/lib/safe-browsing/ephy-gsb-storage.c
+++ b/lib/safe-browsing/ephy-gsb-storage.c
@@ -46,10 +46,10 @@
* The format is {THREAT_TYPE, PLATFORM_TYPE, THREAT_ENTRY_TYPE}.
*/
static const char * const gsb_linux_threat_lists[][3] = {
- {"MALWARE", "LINUX", "URL"},
- {"SOCIAL_ENGINEERING", "LINUX", "URL"},
- {"UNWANTED_SOFTWARE", "LINUX", "URL"},
- {"MALWARE", "LINUX", "IP_RANGE"},
+ {GSB_THREAT_TYPE_MALWARE, "LINUX", "URL"},
+ {GSB_THREAT_TYPE_SOCIAL_ENGINEERING, "LINUX", "URL"},
+ {GSB_THREAT_TYPE_UNWANTED_SOFTWARE, "LINUX", "URL"},
+ {GSB_THREAT_TYPE_MALWARE, "LINUX", "IP_RANGE"},
};
struct _EphyGSBStorage {
diff --git a/lib/safe-browsing/ephy-gsb-utils.h b/lib/safe-browsing/ephy-gsb-utils.h
index 4821c7c..341649a 100644
--- a/lib/safe-browsing/ephy-gsb-utils.h
+++ b/lib/safe-browsing/ephy-gsb-utils.h
@@ -28,6 +28,10 @@ G_BEGIN_DECLS
#define GSB_HASH_TYPE G_CHECKSUM_SHA256
#define GSB_HASH_SIZE (g_checksum_type_get_length (GSB_HASH_TYPE))
+#define GSB_THREAT_TYPE_MALWARE "MALWARE"
+#define GSB_THREAT_TYPE_SOCIAL_ENGINEERING "SOCIAL_ENGINEERING"
+#define GSB_THREAT_TYPE_UNWANTED_SOFTWARE "UNWANTED_SOFTWARE"
+
typedef struct {
char *threat_type;
char *platform_type;
diff --git a/src/ephy-session.c b/src/ephy-session.c
index 76b220a..72a3620 100644
--- a/src/ephy-session.c
+++ b/src/ephy-session.c
@@ -1018,7 +1018,7 @@ confirm_before_recover (EphyWindow *window, const char *url, const char *title)
0);
ephy_web_view_load_error_page (ephy_embed_get_web_view (embed), url,
- EPHY_WEB_VIEW_ERROR_PAGE_CRASH, NULL);
+ EPHY_WEB_VIEW_ERROR_PAGE_CRASH, NULL, NULL);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]