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