mirror of
https://github.com/curl/curl.git
synced 2025-01-18 14:04:30 +08:00
cookies: only consider full path matches
I found a bug which cURL sends cookies to the path not to aim at. For example: - cURL sends a request to http://example.fake/hoge/ - server returns cookie which with path=/hoge; the point is there is NOT the '/' end of path string. - cURL sends a request to http://example.fake/hogege/ with the cookie. The reason for this old "feature" is because that behavior is what is described in the original netscape cookie spec: http://curl.haxx.se/rfc/cookie_spec.html The current cookie spec (RFC6265) clarifies the situation: http://tools.ietf.org/html/rfc6265#section-5.2.4
This commit is contained in:
parent
100a33f7ff
commit
04f52e9b4d
33
lib/cookie.c
33
lib/cookie.c
@ -143,6 +143,34 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool pathmatch(const char* cookie_path, const char* url_path)
|
||||||
|
{
|
||||||
|
size_t cookie_path_len = strlen(cookie_path);
|
||||||
|
size_t url_path_len = strlen(url_path);
|
||||||
|
|
||||||
|
if(url_path_len < cookie_path_len)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* not using checkprefix() because matching should be case-sensitive */
|
||||||
|
if(strncmp(cookie_path, url_path, cookie_path_len))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* it is true if cookie_path and url_path are the same */
|
||||||
|
if(cookie_path_len == url_path_len)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* here, cookie_path_len < url_path_len */
|
||||||
|
|
||||||
|
/* it is false if cookie path is /example and url path is /examples */
|
||||||
|
if(cookie_path[cookie_path_len - 1] != '/') {
|
||||||
|
if(url_path[cookie_path_len] != '/') {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* matching! */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
|
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
|
||||||
*/
|
*/
|
||||||
@ -858,10 +886,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|||||||
|
|
||||||
/* now check the left part of the path with the cookies path
|
/* now check the left part of the path with the cookies path
|
||||||
requirement */
|
requirement */
|
||||||
if(!co->path ||
|
if(!co->path || pathmatch(co->path, path) ) {
|
||||||
/* not using checkprefix() because matching should be
|
|
||||||
case-sensitive */
|
|
||||||
!strncmp(co->path, path, strlen(co->path)) ) {
|
|
||||||
|
|
||||||
/* and now, we know this is a match and we should create an
|
/* and now, we know this is a match and we should create an
|
||||||
entry for the return-linked-list */
|
entry for the return-linked-list */
|
||||||
|
@ -93,6 +93,7 @@ test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
|
|||||||
test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
|
test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
|
||||||
test1216 test1217 test1218 test1219 \
|
test1216 test1217 test1218 test1219 \
|
||||||
test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \
|
test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \
|
||||||
|
test1228 \
|
||||||
\
|
\
|
||||||
test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \
|
test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \
|
||||||
test1308 test1309 test1310 test1311 test1312 test1313 test1314 test1315 \
|
test1308 test1309 test1310 test1311 test1312 test1313 test1314 test1315 \
|
||||||
|
54
tests/data/test1228
Normal file
54
tests/data/test1228
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP GET
|
||||||
|
cookies
|
||||||
|
cookie path
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
<reply>
|
||||||
|
<data>
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Date: Tue, 25 Sep 2001 19:37:44 GMT
|
||||||
|
Set-Cookie: path1=root; domain=.example.fake; path=/;
|
||||||
|
Set-Cookie: path2=depth1; domain=.example.fake; path=/hoge;
|
||||||
|
Content-Length: 34
|
||||||
|
|
||||||
|
This server says cookie path test
|
||||||
|
</data>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP cookie path match
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://example.fake/hoge/1228 http://example.fake/hogege/ -b nonexisting -x %HOSTIP:%HTTPPORT
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET http://example.fake/hoge/1228 HTTP/1.1
|
||||||
|
Host: example.fake
|
||||||
|
Accept: */*
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
|
||||||
|
GET http://example.fake/hogege/ HTTP/1.1
|
||||||
|
Host: example.fake
|
||||||
|
Accept: */*
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
Cookie: path1=root
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
@ -52,8 +52,8 @@ TZ=GMT
|
|||||||
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
|
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
|
||||||
www.loser.com FALSE / FALSE 1139150993 UID 99
|
www.loser.com FALSE / FALSE 1139150993 UID 99
|
||||||
%HOSTIP FALSE / FALSE 1439150993 mooo indeed
|
%HOSTIP FALSE / FALSE 1439150993 mooo indeed
|
||||||
#HttpOnly_%HOSTIP FALSE /w FALSE 1439150993 mooo2 indeed2
|
#HttpOnly_%HOSTIP FALSE /want FALSE 1439150993 mooo2 indeed2
|
||||||
%HOSTIP FALSE /wa FALSE 0 empty
|
%HOSTIP FALSE /want FALSE 0 empty
|
||||||
</file>
|
</file>
|
||||||
</client>
|
</client>
|
||||||
|
|
||||||
@ -77,8 +77,8 @@ Cookie: empty=; mooo2=indeed2; mooo=indeed
|
|||||||
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
|
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
|
||||||
www.loser.com FALSE / FALSE 1139150993 UID 99
|
www.loser.com FALSE / FALSE 1139150993 UID 99
|
||||||
%HOSTIP FALSE / FALSE 1439150993 mooo indeed
|
%HOSTIP FALSE / FALSE 1439150993 mooo indeed
|
||||||
#HttpOnly_%HOSTIP FALSE /w FALSE 1439150993 mooo2 indeed2
|
#HttpOnly_%HOSTIP FALSE /want FALSE 1439150993 mooo2 indeed2
|
||||||
%HOSTIP FALSE /wa FALSE 0 empty
|
%HOSTIP FALSE /want FALSE 0 empty
|
||||||
%HOSTIP FALSE / FALSE 2054030187 ckyPersistent permanent
|
%HOSTIP FALSE / FALSE 2054030187 ckyPersistent permanent
|
||||||
%HOSTIP FALSE / FALSE 0 ckySession temporary
|
%HOSTIP FALSE / FALSE 0 ckySession temporary
|
||||||
%HOSTIP FALSE / FALSE 0 ASPSESSIONIDQGGQQSJJ GKNBDIFAAOFDPDAIEAKDIBKE
|
%HOSTIP FALSE / FALSE 0 ASPSESSIONIDQGGQQSJJ GKNBDIFAAOFDPDAIEAKDIBKE
|
||||||
|
@ -59,7 +59,7 @@ perl -e 'if ("%HOSTIP" !~ /\.0\.0\.1$/) {print "Test only works for HOSTIPs endi
|
|||||||
GET /we/want/8 HTTP/1.1
|
GET /we/want/8 HTTP/1.1
|
||||||
Host: %HOSTIP:%HTTPPORT
|
Host: %HOSTIP:%HTTPPORT
|
||||||
Accept: */*
|
Accept: */*
|
||||||
Cookie: cookie=perhaps; cookie=yes; partmatch=present; foobar=name; blexp=yesyes
|
Cookie: cookie=perhaps; cookie=yes; foobar=name; blexp=yesyes
|
||||||
|
|
||||||
</protocol>
|
</protocol>
|
||||||
</verify>
|
</verify>
|
||||||
|
Loading…
Reference in New Issue
Block a user