[hackers] [surf][PATCH] Implement RefererPolicies

From: nzl <uruabi_AT_gmail.com>
Date: Mon, 19 Nov 2018 04:18:27 -0800

Based on Hiltjo's suggestions and luakit's source.
---
 config.def.h     |  2 ++
 libsurf-webext.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
 surf.c           | 18 +++++++++++++-
 3 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 8cdc397..e93ba1f 100644
--- a/config.def.h
+++ b/config.def.h
_AT_@ -37,6 +37,7 @@ static Parameter defconfig[ParameterLast] = {
 	[MediaManualPlay]     =       { { .i = 1 },     },
 	[Plugins]             =       { { .i = 1 },     },
 	[PreferredLanguages]  =       { { .v = (char *[]){ NULL } }, },
+	[RefererPolicies]     =       { { .v = "E#_AT_e" },},
 	[RunInFullscreen]     =       { { .i = 0 },     },
 	[ScrollBars]          =       { { .i = 1 },     },
 	[ShowIndicators]      =       { { .i = 1 },     },
_AT_@ -168,6 +169,7 @@ static Key keys[] = {
 	{ MODKEY,                GDK_KEY_t,      showcert,   { 0 } },
 
 	{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_a,      togglecookiepolicy, { 0 } },
+	{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_e,      togglerefererpolicy, { 0 } },
 	{ 0,                     GDK_KEY_F11,    togglefullscreen, { 0 } },
 	{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_o,      toggleinspector, { 0 } },
 
diff --git a/libsurf-webext.c b/libsurf-webext.c
index 684d4a5..1bc8da7 100644
--- a/libsurf-webext.c
+++ b/libsurf-webext.c
_AT_@ -20,6 +20,7 @@ typedef struct Page {
 
 static int pipein, pipeout;
 static Page *pages;
+static int refererpolicy;
 
 Page *
 newpage(WebKitWebPage *page)
_AT_@ -95,15 +96,76 @@ readpipe(GIOChannel *s, GIOCondition c, gpointer unused)
 		webkit_dom_dom_window_scroll_by(view,
 		                                0, (wh / 100) * msg[2]);
 		break;
+	case 'r':
+		refererpolicy = msg[2];
+		break;
 	}
 
 	return TRUE;
 }
 
+static int
+originlen(const char *url)
+{
+	const char *p;
+
+	p = strstr(url, "://");
+	p = p ? p + 3 : url;
+	while (*p && *p != '/')
+		++p;
+	return p - url;
+}
+
+static int
+sameorigin(const gchar *u1, const gchar *u2)
+{
+	int l1, l2;
+
+	l1 = originlen(u1);
+	l2 = originlen(u2);
+	return l1 == l2 && memcmp(u1, u2, l1) == 0;
+}
+
+static gboolean
+webpagesendrequest(WebKitWebPage *wp, WebKitURIRequest *req, WebKitURIResponse *res,
+                  gpointer unused)
+{
+	SoupMessageHeaders *h = webkit_uri_request_get_http_headers(req);
+	const char *referer;
+	char *origin;
+
+	if (!h)
+		return FALSE;
+	switch (refererpolicy) {
+	case 'e': /* disallow */
+		soup_message_headers_remove(h, "Referer");
+		break;
+	case '_AT_': /* allow if same-origin */
+		referer = soup_message_headers_get_one(h, "Referer");
+		if (referer && !sameorigin(referer, webkit_uri_request_get_uri(req)))
+			soup_message_headers_remove(h, "Referer");
+		break;
+	case '#': /* strip path if cross-origin */
+		referer = soup_message_headers_get_one(h, "Referer");
+		if (referer && !sameorigin(referer, webkit_uri_request_get_uri(req))) {
+			origin = g_strdup(referer);
+			origin[originlen(origin)] = '\0';
+			soup_message_headers_replace(h, "Referer", origin);
+			g_free(origin);
+		}
+		break;
+	default:
+	case 'E': /* allow */
+		break;
+	}
+	return FALSE;
+}
+
 static void
 webpagecreated(WebKitWebExtension *e, WebKitWebPage *wp, gpointer unused)
 {
 	Page *p = newpage(wp);
+	g_signal_connect(wp, "send-request", G_CALLBACK(webpagesendrequest), NULL);
 }
 
 G_MODULE_EXPORT void
_AT_@ -111,6 +173,7 @@ webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e, GVariant *
 {
 	GIOChannel *gchanpipe;
 
+	refererpolicy = 'E';
 	g_signal_connect(e, "page-created", G_CALLBACK(webpagecreated), NULL);
 
 	g_variant_get(gv, "(ii)", &pipein, &pipeout);
diff --git a/surf.c b/surf.c
index d48fbc9..b753cf0 100644
--- a/surf.c
+++ b/surf.c
_AT_@ -71,6 +71,7 @@ typedef enum {
 	MediaManualPlay,
 	Plugins,
 	PreferredLanguages,
+	RefererPolicies,
 	RunInFullscreen,
 	ScrollBars,
 	ShowIndicators,
_AT_@ -229,6 +230,7 @@ static void stop(Client *c, const Arg *a);
 static void toggle(Client *c, const Arg *a);
 static void togglefullscreen(Client *c, const Arg *a);
 static void togglecookiepolicy(Client *c, const Arg *a);
+static void togglerefererpolicy(Client *c, const Arg *a);
 static void toggleinspector(Client *c, const Arg *a);
 static void find(Client *c, const Arg *a);
 
_AT_@ -244,6 +246,7 @@ static Atom atoms[AtomLast];
 static Window embed;
 static int showxid;
 static int cookiepolicy;
+static int refererpolicy;
 static Display *dpy;
 static Client *clients;
 static GdkDevice *gdkkb;
_AT_@ -656,7 +659,8 @@ gettogglestats(Client *c)
 	togglestats[8] = curconfig[FrameFlattening].val.i ? 'F' : 'f';
 	togglestats[9] = curconfig[Certificate].val.i ?     'X' : 'x';
 	togglestats[10] = curconfig[StrictTLS].val.i ?      'T' : 't';
-	togglestats[11] = '\0';
+	togglestats[11] = ((char *)curconfig[RefererPolicies].val.v)[refererpolicy];
+	togglestats[12] = '\0';
 }
 
 void
_AT_@ -1904,6 +1908,18 @@ togglecookiepolicy(Client *c, const Arg *a)
 	setparameter(c, 0, CookiePolicies, NULL);
 }
 
+void
+togglerefererpolicy(Client *c, const Arg *unused)
+{
+	Arg a;
+
+	++refererpolicy;
+	refererpolicy %= strlen(curconfig[RefererPolicies].val.v);
+	a.i = ((char *)curconfig[RefererPolicies].val.v)[refererpolicy];
+	msgext(c, 'r', &a);
+	updatetitle(c);
+}
+
 void
 toggleinspector(Client *c, const Arg *a)
 {
-- 
2.19.1
Received on Mon Nov 19 2018 - 13:18:27 CET

This archive was generated by hypermail 2.3.0 : Mon Nov 19 2018 - 13:24:22 CET