Hi all,

Firstly, I would like to thank everyone for the surf browser. Its
simplicity is a thing of beauty, and working with it has been a pleasure. I
have added features easily, and its code is easy to audit, which means
security issues can be found and fixed easily, even by a random user like
me.

The config.def.h file has a define for DOWNLOAD that just opens up curl,
and surf.c calls DOWNLOAD without any prompting.

The situation is simple. If you launch surf from the home folder, a very
common and expected thing to do, then any website can either:
1. use an img src=".bashrc" to install a .bashrc file.
2. use javascript window.location.assign, possibly after a delay to exploit
it when you are away, installing a .bashrc file. (disabling javascript
fixes that case, but an HTTP redirect will do the same thing)

Basically, in several cases, surf will happily install a .bashrc file in
your home folder. And since the shell sucks in this way, and will execute
it on login even with the default umask that doesn't set the execute bit,
the next time you login with bash, the code will be executed.

A proof of concept is here:
http://benwoolley.org/exploit.html

Just run the following to install the .bashrc file
cd; surf http://benwoolley.org/exploit.html

To run it, just execute `bash` and you will see the following message
echo'd:
Exploit succeeded!

A simple workaround is to simply launch surf outside of the home folder,
like, say, a download folder. For example, launch it with:
#!/bin/sh
mkdir -p ~/Downloads && cd ~/Downloads && surf "$@"

You can also change the DOWNLOAD define to cd into a particular download
folder before launching curl.

My first attachment is a patch that adds support for a download folder.

My second attachment is a patch that only initiates a DOWNLOAD call from
navigations from the top-most frame. That fixes the problem where random ad
network files will download automatically. I noticed that problem while
testing slashdot.org. I am not sure if that code actually fixes the img src
case, but it has fixed the one case I ran into.

I grouped these patches together because they all relate to issues with the
download mechanism. Other, unrelated patches are coming.

Thank you,

Ben
From 5a0eccaf232a5123a56f2425fd9abb2699b3b77e Mon Sep 17 00:00:00 2001
From: Ben Woolley <tauto...@gmail.com>
Date: Wed, 7 Jan 2015 10:13:26 -0800
Subject: [PATCH] Add a download folder to avoid drive-by .bashrc installation
 and such.

---
 config.def.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/config.def.h b/config.def.h
index 80a0feb..af47879 100644
--- a/config.def.h
+++ b/config.def.h
@@ -2,6 +2,7 @@
 static char *useragent      = "Mozilla/5.0 (X11; U; Unix; en-US) "
 	"AppleWebKit/537.15 (KHTML, like Gecko) Chrome/24.0.1295.0 "
 	"Safari/537.15 Surf/"VERSION;
+static char *downloadfolder = "~/Downloads/";
 static char *stylefile      = "~/.surf/style.css";
 static char *scriptfile     = "~/.surf/script.js";
 
@@ -42,10 +43,10 @@ static Bool allowgeolocation = TRUE;
 /* DOWNLOAD(URI, referer) */
 #define DOWNLOAD(d, r) { \
 	.v = (char *[]){ "/bin/sh", "-c", \
-		"st -e /bin/sh -c \"curl -L -J -O --user-agent '$1'" \
+		"st -e /bin/sh -c \"mkdir -p $4 && cd $4 && curl -L -J -O --user-agent '$1'" \
 		" --referer '$2' -b $3 -c $3 '$0';" \
 		" sleep 5;\"", \
-		d, useragent, r, cookiefile, NULL \
+		d, useragent, r, cookiefile, downloadfolder, NULL \
 	} \
 }
 
-- 
2.1.2

From 668750b3ab157f1ad66654a66d845efee9783cb8 Mon Sep 17 00:00:00 2001
From: Ben Woolley <tauto...@gmail.com>
Date: Wed, 7 Jan 2015 10:23:42 -0800
Subject: [PATCH] Only initiate a download from the top frame.

---
 surf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/surf.c b/surf.c
index 6beda59..5b994de 100644
--- a/surf.c
+++ b/surf.c
@@ -409,7 +409,7 @@ createwindow(WebKitWebView  *v, WebKitWebFrame *f, Client *c) {
 static gboolean
 decidedownload(WebKitWebView *v, WebKitWebFrame *f, WebKitNetworkRequest *r,
 		gchar *m,  WebKitWebPolicyDecision *p, Client *c) {
-	if(!webkit_web_view_can_show_mime_type(v, m)) {
+	if(!webkit_web_view_can_show_mime_type(v, m) && !webkit_web_frame_get_parent(f)) {
 		webkit_web_policy_decision_download(p);
 		return TRUE;
 	}
-- 
2.1.2

Reply via email to