From a964be6bd96583f8735fd297856f1c9845850f6a Mon Sep 17 00:00:00 2001 From: Dylan Simon Date: Wed, 14 Sep 2011 17:30:42 -0400 Subject: preserve HttpOnly flag on cookies to prevent XSS attacks --- examples/data/plugins/cookies.py | 16 +++++++++++++--- src/commands.c | 13 +++++++++---- src/cookie-jar.c | 4 +++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/examples/data/plugins/cookies.py b/examples/data/plugins/cookies.py index e29ee36..a09cf69 100644 --- a/examples/data/plugins/cookies.py +++ b/examples/data/plugins/cookies.py @@ -39,7 +39,9 @@ class TextStore(object): 'TRUE' : 'https', 'FALSE' : 'http' } + extra = '' if cookie[0].startswith("#HttpOnly_"): + extra = 'Only' domain = cookie[0][len("#HttpOnly_"):] elif cookie[0].startswith('#'): return None @@ -50,7 +52,7 @@ class TextStore(object): cookie[2], cookie[5], cookie[6], - scheme[cookie[3]], + scheme[cookie[3]] + extra, cookie[4]) except (KeyError,IndexError): # Let malformed rows pass through like comments @@ -60,9 +62,17 @@ class TextStore(object): """Convert cookie event to cookie.txt row""" secure = { 'https' : 'TRUE', - 'http' : 'FALSE' + 'http' : 'FALSE', + 'httpsOnly' : 'TRUE', + 'httpOnly' : 'FALSE' } - return (cookie[0], + http_only = { + 'https' : '', + 'http' : '', + 'httpsOnly' : '#HttpOnly_', + 'httpOnly' : '#HttpOnly_' + } + return (http_only[cookie[4]] + cookie[0], 'TRUE' if cookie[0].startswith('.') else 'FALSE', cookie[1], secure[cookie[4]], diff --git a/src/commands.c b/src/commands.c index 7689ea1..85057b3 100644 --- a/src/commands.c +++ b/src/commands.c @@ -241,8 +241,8 @@ show_inspector(WebKitWebView *page, GArray *argv, GString *result) { void add_cookie(WebKitWebView *page, GArray *argv, GString *result) { (void) page; (void) result; - gchar *host, *path, *name, *value; - gboolean secure = 0; + gchar *host, *path, *name, *value, *scheme; + gboolean secure = 0, httponly = 0; SoupDate *expires = NULL; if(argv->len != 6) @@ -253,14 +253,19 @@ add_cookie(WebKitWebView *page, GArray *argv, GString *result) { path = argv_idx (argv, 1); name = argv_idx (argv, 2); value = argv_idx (argv, 3); - secure = strcmp (argv_idx (argv, 4), "https") == 0; - if (strlen (argv_idx (argv, 5)) != 0) + scheme = argv_idx (argv, 4); + if (strncmp (scheme, "http", 4) == 0) { + secure = scheme[4] == 's'; + httponly = strncmp (&scheme[4+secure], "Only", 4) == 0; + } + if (argv->len >= 6 && *argv_idx (argv, 5)) expires = soup_date_new_from_time_t ( strtoul (argv_idx (argv, 5), NULL, 10)); // Create new cookie SoupCookie * cookie = soup_cookie_new (name, value, host, path, -1); soup_cookie_set_secure (cookie, secure); + soup_cookie_set_http_only (cookie, httponly); if (expires) soup_cookie_set_expires (cookie, expires); diff --git a/src/cookie-jar.c b/src/cookie-jar.c index dd9585b..2f6be83 100644 --- a/src/cookie-jar.c +++ b/src/cookie-jar.c @@ -40,7 +40,9 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { * command because otherwise a loop would occur when a cookie change is * propagated to other uzbl instances using add/delete_cookie. */ if(!uzbl_jar->in_manual_add) { - gchar *scheme = cookie->secure ? "https" : "http"; + gchar *scheme = cookie->secure + ? cookie->http_only ? "httpsOnly" : "https" + : cookie->http_only ? "httpOnly" : "http"; gchar *expires = NULL; if(cookie->expires) -- cgit v1.2.3