aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES8
-rw-r--r--RELEASE-NOTES4
-rw-r--r--lib/cookie.c21
-rw-r--r--lib/cookie.h1
-rw-r--r--tests/data/test312
-rw-r--r--tests/data/test464
6 files changed, 36 insertions, 4 deletions
diff --git a/CHANGES b/CHANGES
index 6039fd6ed..02a476c0f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,14 @@
Changelog
Daniel S (31 Jan 2008)
+- Niklas Angebrand made the cookie support in libcurl properly deal with the
+ "HttpOnly" feature introduced by Microsoft and apparently also supported by
+ Firefox: http://msdn2.microsoft.com/en-us/library/ms533046.aspx . HttpOnly
+ is now supported when received from servers in HTTP headers, when written to
+ cookie jars and when read from existing cookie jars.
+
+ I modified test case 31 and 46 to also do some basic HttpOnly testing.
+
- Dmitry Kurochkin moved several struct fields from the connectdata struct to
the SingleRequest one to make pipelining better. It is a bit tricky to keep
them in the right place, to keep things related to the actual request or to
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index b8eabdb92..9c590e55d 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -10,7 +10,7 @@ Curl and libcurl 7.18.1
This release includes the following changes:
- o
+ o added support for HttpOnly cookies
This release includes the following bugfixes:
@@ -31,6 +31,6 @@ New curl mirrors:
This release would not have looked like this without help, code, reports and
advice from friends like these:
- Michal Marek, Dmitry Kurochkin
+ Michal Marek, Dmitry Kurochkin, Niklas Angebrand
Thanks! (and sorry if I forgot to mention someone)
diff --git a/lib/cookie.c b/lib/cookie.c
index 3e6c8a1cd..f2dabd8e2 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -367,8 +367,12 @@ Curl_cookie_add(struct SessionHandle *data,
else {
if(sscanf(ptr, "%" MAX_COOKIE_LINE_TXT "[^;\r\n]",
what)) {
- if(strequal("secure", what))
+ if(strequal("secure", what)) {
co->secure = TRUE;
+ }
+ else if (strequal("httponly", what)) {
+ co->httponly = TRUE;
+ }
/* else,
unsupported keyword without assign! */
@@ -433,6 +437,19 @@ Curl_cookie_add(struct SessionHandle *data,
char *tok_buf;
int fields;
+ /* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies
+ marked with httpOnly after the domain name are not accessible
+ from javascripts, but since curl does not operate at javascript
+ level, we include them anyway. In Firefox's cookie files, these
+ lines are preceeded with #HttpOnly_ and then everything is
+ as usual, so we skip 10 characters of the line..
+ */
+ if (strncmp(lineptr, "#HttpOnly_", 10) == 0) {
+ lineptr += 10;
+ co->httponly = TRUE;
+ }
+
+
if(lineptr[0]=='#') {
/* don't even try the comments */
free(co);
@@ -918,6 +935,7 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
static char *get_netscape_format(const struct Cookie *co)
{
return aprintf(
+ "%s" /* httponly preamble */
"%s%s\t" /* domain */
"%s\t" /* tailmatch */
"%s\t" /* path */
@@ -925,6 +943,7 @@ static char *get_netscape_format(const struct Cookie *co)
"%" FORMAT_OFF_T "\t" /* expires */
"%s\t" /* name */
"%s", /* value */
+ co->httponly?"#HttpOnly_":"",
/* Make sure all domains are prefixed with a dot if they allow
tailmatching. This is Mozilla-style. */
(co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
diff --git a/lib/cookie.h b/lib/cookie.h
index 7fbc72e8a..a1d107352 100644
--- a/lib/cookie.h
+++ b/lib/cookie.h
@@ -50,6 +50,7 @@ struct Cookie {
bool secure; /* whether the 'secure' keyword was used */
bool livecookie; /* updated from a server, not a stored file */
+ bool httponly; /* true if the httponly directive is present */
};
struct CookieInfo {
diff --git a/tests/data/test31 b/tests/data/test31
index a0a9ce9b0..444a9b13e 100644
--- a/tests/data/test31
+++ b/tests/data/test31
@@ -26,6 +26,7 @@ Set-Cookie: nodomain=value; expires=Fri Feb 2 11:56:27 GMT 2035
Set-Cookie: novalue; domain=reallysilly
Set-Cookie: test=yes; domain=foo.com; expires=Sat Feb 2 11:56:27 GMT 2030
Set-Cookie: test2=yes; domain=se; expires=Sat Feb 2 11:56:27 GMT 2030
+Set-Cookie: magic=yessir; path=/silly/; HttpOnly
boo
</data>
@@ -69,6 +70,7 @@ Accept: */*
.127.0.0.1 TRUE /silly/ FALSE 0 ismatch this
.127.0.0.1 TRUE / FALSE 0 partmatch present
127.0.0.1 FALSE /we/want/ FALSE 2054030187 nodomain value
+#HttpOnly_127.0.0.1 FALSE /silly/ FALSE 0 magic yessir
</file>
</verify>
</testcase>
diff --git a/tests/data/test46 b/tests/data/test46
index bc0821904..56ad85958 100644
--- a/tests/data/test46
+++ b/tests/data/test46
@@ -51,6 +51,7 @@ TZ=GMT
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
www.loser.com FALSE / FALSE 1139150993 UID 99
%HOSTIP FALSE / FALSE 1439150993 mooo indeed
+#HttpOnly_%HOSTIP FALSE / FALSE 1439150993 mooo2 indeed2
%HOSTIP FALSE / FALSE 0 empty
</file>
</client>
@@ -64,7 +65,7 @@ www.loser.com FALSE / FALSE 1139150993 UID 99
GET /want/46 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
-Cookie: empty=; mooo=indeed
+Cookie: empty=; mooo2=indeed2; mooo=indeed
</protocol>
<file name="log/jar46" mode="text">
@@ -75,6 +76,7 @@ Cookie: empty=; mooo=indeed
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
www.loser.com FALSE / FALSE 1139150993 UID 99
%HOSTIP FALSE / FALSE 1439150993 mooo indeed
+#HttpOnly_%HOSTIP FALSE / FALSE 1439150993 mooo2 indeed2
%HOSTIP FALSE / FALSE 0 empty
%HOSTIP FALSE / FALSE 2054030187 ckyPersistent permanent
%HOSTIP FALSE / FALSE 0 ckySession temporary