components/curl/patches/015-CVE-2014-3613-part1.patch
branchs11u2-sru
changeset 4799 f6da2b76c51b
parent 4772 51a400f647ed
child 4800 5aa28a7db635
equal deleted inserted replaced
4772:51a400f647ed 4799:f6da2b76c51b
     1 From eac573ea9c368f5e3c07de4d5ec5c5d0f84a021a Mon Sep 17 00:00:00 2001
       
     2 From: Tim Ruehsen <[email protected]>
       
     3 Date: Tue, 19 Aug 2014 21:01:28 +0200
       
     4 Subject: [PATCH 1/2] cookies: only use full host matches for hosts used as IP
       
     5  address
       
     6 
       
     7 By not detecting and rejecting domain names for partial literal IP
       
     8 addresses properly when parsing received HTTP cookies, libcurl can be
       
     9 fooled to both send cookies to wrong sites and to allow arbitrary sites
       
    10 to set cookies for others.
       
    11 
       
    12 Bug: http://curl.haxx.se/docs/adv_20140910.html
       
    13 ---
       
    14  lib/cookie.c        | 50 ++++++++++++++++++++++++++++++++++++++----------
       
    15  tests/data/test1105 |  3 +--
       
    16  tests/data/test31   | 55 +++++++++++++++++++++++++++--------------------------
       
    17  tests/data/test8    |  3 ++-
       
    18  4 files changed, 71 insertions(+), 40 deletions(-)
       
    19 
       
    20 This problem has been fixed upstream in curl version 7.38.0
       
    21 
       
    22 --- lib/cookie.c.orig	2014-09-04 10:25:26.404578422 -0700
       
    23 +++ lib/cookie.c	2014-09-04 10:40:04.769726955 -0700
       
    24 @@ -97,6 +97,7 @@
       
    25  #include "strtoofft.h"
       
    26  #include "rawstr.h"
       
    27  #include "curl_memrchr.h"
       
    28 +#include "inet_pton.h"
       
    29  
       
    30  /* The last #include file should be: */
       
    31  #include "memdebug.h"
       
    32 @@ -181,6 +182,27 @@
       
    33    *str = strdup(newstr);
       
    34  }
       
    35  
       
    36 +/*
       
    37 + * Return true if the given string is an IP(v4|v6) address.
       
    38 + */
       
    39 +static bool isip(const char *domain)
       
    40 +{
       
    41 +  struct in_addr addr;
       
    42 +#ifdef ENABLE_IPV6
       
    43 +  struct in6_addr addr6;
       
    44 +#endif
       
    45 +
       
    46 +  if(Curl_inet_pton(AF_INET, domain, &addr)
       
    47 +#ifdef ENABLE_IPV6
       
    48 +     || Curl_inet_pton(AF_INET6, domain, &addr6)
       
    49 +#endif
       
    50 +    ) {
       
    51 +    /* domain name given as IP address */
       
    52 +    return TRUE;
       
    53 +  }
       
    54 +
       
    55 +  return FALSE;
       
    56 +}
       
    57  
       
    58  /****************************************************************************
       
    59   *
       
    60 @@ -280,6 +302,8 @@
       
    61              }
       
    62            }
       
    63            else if(Curl_raw_equal("domain", name)) {
       
    64 +            bool is_ip;
       
    65 +
       
    66              /* note that this name may or may not have a preceeding dot, but
       
    67                 we don't care about that, we treat the names the same anyway */
       
    68  
       
    69 @@ -321,18 +345,19 @@
       
    70                if('.' == whatptr[0])
       
    71                  whatptr++; /* ignore preceeding dot */
       
    72  
       
    73 -              if(!domain || tailmatch(whatptr, domain)) {
       
    74 -                const char *tailptr=whatptr;
       
    75 -                if(tailptr[0] == '.')
       
    76 -                  tailptr++;
       
    77 -                strstore(&co->domain, tailptr); /* don't prefix w/dots
       
    78 -                                                   internally */
       
    79 +              is_ip = isip(domain ? domain : whatptr);
       
    80 +
       
    81 +              if(!domain
       
    82 +                 || (is_ip && !strcmp(whatptr, domain))
       
    83 +                 || (!is_ip && tailmatch(whatptr, domain))) {
       
    84 +                strstore(&co->domain, whatptr);
       
    85                  if(!co->domain) {
       
    86                    badcookie = TRUE;
       
    87                    break;
       
    88                  }
       
    89 -                co->tailmatch=TRUE; /* we always do that if the domain name was
       
    90 -                                       given */
       
    91 +                if(!is_ip)
       
    92 +                  co->tailmatch=TRUE; /* we always do that if the domain name
       
    93 +                                         was given */
       
    94                }
       
    95                else {
       
    96                  /* we did not get a tailmatch and then the attempted set domain
       
    97 @@ -821,10 +846,14 @@
       
    98    time_t now = time(NULL);
       
    99    struct Cookie *mainco=NULL;
       
   100    size_t matches = 0;
       
   101 +  bool is_ip;
       
   102  
       
   103    if(!c || !c->cookies)
       
   104      return NULL; /* no cookie struct or no cookies in the struct */
       
   105  
       
   106 +  /* check if host is an IP(v4|v6) address */
       
   107 +  is_ip = isip(host);
       
   108 +
       
   109    co = c->cookies;
       
   110  
       
   111    while(co) {
       
   112 @@ -836,8 +865,8 @@
       
   113  
       
   114        /* now check if the domain is correct */
       
   115        if(!co->domain ||
       
   116 -         (co->tailmatch && tailmatch(co->domain, host)) ||
       
   117 -         (!co->tailmatch && Curl_raw_equal(host, co->domain)) ) {
       
   118 +         (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
       
   119 +         ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
       
   120          /* the right part of the host matches the domain stuff in the
       
   121             cookie data */
       
   122  
       
   123 --- tests/data/test1105.orig	2014-09-04 10:27:20.052223915 -0700
       
   124 +++ tests/data/test1105	2014-09-04 10:41:18.310085197 -0700
       
   125 @@ -56,8 +56,7 @@
       
   126  # This file was generated by libcurl! Edit at your own risk.
       
   127  
       
   128  127.0.0.1	FALSE	/we/want/	FALSE	0	foobar	name
       
   129 -.127.0.0.1	TRUE	"/silly/"	FALSE	0	mismatch	this
       
   130 -.0.0.1	TRUE	/	FALSE	0	partmatch	present
       
   131 +127.0.0.1	FALSE	"/silly/"	FALSE	0	mismatch	this
       
   132  </file>
       
   133  </verify>
       
   134  </testcase>
       
   135 --- tests/data/test31.orig	2014-09-04 10:27:10.395450839 -0700
       
   136 +++ tests/data/test31	2014-09-04 11:27:38.685969246 -0700
       
   137 @@ -18,6 +18,30 @@
       
   138  Funny-head: yesyes
       
   139  Set-Cookie: foobar=name; domain=anything.com; path=/ ; secure
       
   140  Set-Cookie:ismatch=this  ; domain=127.0.0.1; path=/silly/
       
   141 +Set-Cookie: overwrite=this  ; domain=127.0.0.1; path=/overwrite/
       
   142 +Set-Cookie: overwrite=this2  ; domain=127.0.0.1; path=/overwrite
       
   143 +Set-Cookie: sec1value=secure1  ; domain=127.0.0.1; path=/secure1/ ; secure
       
   144 +Set-Cookie: sec2value=secure2  ; domain=127.0.0.1; path=/secure2/ ; secure=
       
   145 +Set-Cookie: sec3value=secure3  ; domain=127.0.0.1; path=/secure3/ ; secure=
       
   146 +Set-Cookie: sec4value=secure4  ; secure=; domain=127.0.0.1; path=/secure4/ ; 
       
   147 +Set-Cookie: sec5value=secure5  ; secure; domain=127.0.0.1; path=/secure5/ ; 
       
   148 +Set-Cookie: sec6value=secure6  ; secure ; domain=127.0.0.1; path=/secure6/ ; 
       
   149 +Set-Cookie: sec7value=secure7  ; secure   ; domain=127.0.0.1; path=/secure7/ ; 
       
   150 +Set-Cookie: sec8value=secure8  ; secure= ; domain=127.0.0.1; path=/secure8/ ; 
       
   151 +Set-Cookie: secure=very1  ; secure=; domain=127.0.0.1; path=/secure9/; 
       
   152 +Set-Cookie: httpo1=value1  ; domain=127.0.0.1; path=/p1/; httponly
       
   153 +Set-Cookie: httpo2=value2  ; domain=127.0.0.1; path=/p2/; httponly=
       
   154 +Set-Cookie: httpo3=value3  ; httponly; domain=127.0.0.1; path=/p3/;
       
   155 +Set-Cookie: httpo4=value4  ; httponly=; domain=127.0.0.1; path=/p4/; 
       
   156 +Set-Cookie: httponly=myvalue1  ; domain=127.0.0.1; path=/p4/; httponly
       
   157 +Set-Cookie: httpandsec=myvalue2  ; domain=127.0.0.1; path=/p4/; httponly; secure
       
   158 +Set-Cookie: httpandsec2=myvalue3; domain=127.0.0.1; path=/p4/; httponly=; secure
       
   159 +Set-Cookie: httpandsec3=myvalue4  ; domain=127.0.0.1; path=/p4/; httponly; secure=
       
   160 +Set-Cookie: httpandsec4=myvalue5  ; domain=127.0.0.1; path=/p4/; httponly=; secure=
       
   161 +Set-Cookie: httpandsec5=myvalue6  ; domain=127.0.0.1; path=/p4/; secure; httponly=
       
   162 +Set-Cookie: httpandsec6=myvalue7  ; domain=127.0.0.1; path=/p4/; secure=; httponly=
       
   163 +Set-Cookie: httpandsec7=myvalue8  ; domain=127.0.0.1; path=/p4/; secure; httponly
       
   164 +Set-Cookie: httpandsec8=myvalue9; domain=127.0.0.1; path=/p4/; secure=; httponly
       
   165  Set-Cookie: partmatch=present; domain=127.0.0.1 ; path=/;
       
   166  Set-Cookie:eat=this; domain=moo.foo.moo;
       
   167  Set-Cookie: eat=this-too; domain=.foo.moo;
       
   168 @@ -27,7 +51,8 @@
       
   169  Set-Cookie: test=yes; domain=foo.com; expires=Sat Feb 2 11:56:27 GMT 2030
       
   170  Set-Cookie: test2=yes; domain=se; expires=Sat Feb 2 11:56:27 GMT 2030
       
   171  Set-Cookie: magic=yessir; path=/silly/; HttpOnly
       
   172 -Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad;
       
   173 +Set-Cookie: blexp=yesyes; domain=127.0.0.1; domain=127.0.0.1; expiry=totally bad;
       
   174 +Set-Cookie: partialip=nono; domain=.0.0.1;
       
   175  
       
   176  boo
       
   177  </data>
       
   178 @@ -50,6 +75,9 @@
       
   179   <command>
       
   180  http://%HOSTIP:%HTTPPORT/we/want/31 -b none -c log/jar31.txt
       
   181  </command>
       
   182 +<precheck>
       
   183 +perl -e 'if ("%HOSTIP" !~ /127\.0\.0\.1$/) {print "Test only works for HOSTIP 127.0.0.1"; exit(1)}'
       
   184 +</precheck>
       
   185  </client>
       
   186  
       
   187  # Verify data after the test has been "shot"
       
   188 @@ -68,11 +96,35 @@
       
   189  # http://curl.haxx.se/rfc/cookie_spec.html
       
   190  # This file was generated by libcurl! Edit at your own risk.
       
   191  
       
   192 -.127.0.0.1	TRUE	/silly/	FALSE	0	ismatch	this
       
   193 -.127.0.0.1	TRUE	/	FALSE	0	partmatch	present
       
   194 +127.0.0.1	FALSE	/silly/	FALSE	0	ismatch	this
       
   195 +127.0.0.1	FALSE	/overwrite/	FALSE	0	overwrite	this
       
   196 +127.0.0.1	FALSE	/overwrite	FALSE	0	overwrite	this2
       
   197 +127.0.0.1	FALSE	/secure1/	TRUE	0	sec1value	secure1
       
   198 +127.0.0.1	FALSE	/secure2/	FALSE	0	sec2value	secure2
       
   199 +127.0.0.1	FALSE	/secure3/	FALSE	0	sec3value	secure3
       
   200 +127.0.0.1	FALSE	/secure4/	FALSE	0	sec4value	secure4
       
   201 +127.0.0.1	FALSE	/secure5/	TRUE	0	sec5value	secure5
       
   202 +127.0.0.1	FALSE	/secure6/	FALSE	0	sec6value	secure6
       
   203 +127.0.0.1	FALSE	/secure7/	FALSE	0	sec7value	secure7
       
   204 +127.0.0.1	FALSE	/secure8/	FALSE	0	sec8value	secure8
       
   205 +127.0.0.1	FALSE	/secure9/	FALSE	0	secure	very1
       
   206 +#HttpOnly_127.0.0.1	FALSE	/p1/	FALSE	0	httpo1	value1
       
   207 +127.0.0.1	FALSE	/p2/	FALSE	0	httpo2	value2
       
   208 +#HttpOnly_127.0.0.1	FALSE	/p3/	FALSE	0	httpo3	value3
       
   209 +127.0.0.1	FALSE	/p4/	FALSE	0	httpo4	value4
       
   210 +#HttpOnly_127.0.0.1	FALSE	/p4/	FALSE	0	httponly	myvalue1
       
   211 +#HttpOnly_127.0.0.1	FALSE	/p4/	TRUE	0	httpandsec	myvalue2
       
   212 +127.0.0.1	FALSE	/p4/	TRUE	0	httpandsec2	myvalue3
       
   213 +#HttpOnly_127.0.0.1	FALSE	/p4/	FALSE	0	httpandsec3	myvalue4
       
   214 +127.0.0.1	FALSE	/p4/	FALSE	0	httpandsec4	myvalue5
       
   215 +127.0.0.1	FALSE	/p4/	TRUE	0	httpandsec5	myvalue6
       
   216 +127.0.0.1	FALSE	/p4/	FALSE	0	httpandsec6	myvalue7
       
   217 +#HttpOnly_127.0.0.1	FALSE	/p4/	TRUE	0	httpandsec7	myvalue8
       
   218 +#HttpOnly_127.0.0.1	FALSE	/p4/	FALSE	0	httpandsec8	myvalue9
       
   219 +127.0.0.1	FALSE	/	FALSE	0	partmatch	present
       
   220  127.0.0.1	FALSE	/we/want/	FALSE	2054030187	nodomain	value
       
   221  #HttpOnly_127.0.0.1	FALSE	/silly/	FALSE	0	magic	yessir
       
   222 -.0.0.1	TRUE	/we/want/	FALSE	0	blexp	yesyes
       
   223 +127.0.0.1	FALSE	/we/want/	FALSE	0	blexp	yesyes
       
   224  </file>
       
   225  </verify>
       
   226  </testcase>
       
   227 --- tests/data/test8.orig	2014-09-04 10:27:04.885231628 -0700
       
   228 +++ tests/data/test8	2014-09-04 10:41:44.133914601 -0700
       
   229 @@ -35,16 +35,20 @@
       
   230  Server: test-server/fake
       
   231  Content-Type: text/html
       
   232  Funny-head: yesyes
       
   233 -Set-Cookie: foobar=name; domain=127.0.0.1; path=/;
       
   234 -Set-Cookie: mismatch=this; domain=127.0.0.1; path="/silly/";
       
   235 +Set-Cookie: foobar=name; domain=%HOSTIP; path=/;
       
   236 +Set-Cookie: mismatch=this; domain=%HOSTIP; path="/silly/";
       
   237  Set-Cookie: partmatch=present; domain=.0.0.1; path=/w;
       
   238  Set-Cookie: duplicate=test; domain=.0.0.1; domain=.0.0.1; path=/donkey;
       
   239  Set-Cookie: cookie=yes; path=/we;
       
   240  Set-Cookie: cookie=perhaps; path=/we/want;
       
   241  Set-Cookie: nocookie=yes; path=/WE;
       
   242 -Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad;
       
   243 +Set-Cookie: blexp=yesyes; domain=%HOSTIP; domain=%HOSTIP; expiry=totally bad;
       
   244 +Set-Cookie: partialip=nono; domain=.0.0.1;
       
   245  
       
   246  </file>
       
   247 +<precheck>
       
   248 +perl -e 'if ("%HOSTIP" !~ /\.0\.0\.1$/) {print "Test only works for HOSTIPs ending with .0.0.1"; exit(1)}'
       
   249 +</precheck>
       
   250  </client>
       
   251  
       
   252  # Verify data after the test has been "shot"
       
   253 @@ -56,7 +60,7 @@
       
   254  GET /we/want/8 HTTP/1.1
       
   255  Host: %HOSTIP:%HTTPPORT
       
   256  Accept: */*
       
   257 -Cookie: cookie=perhaps; cookie=yes; partmatch=present; foobar=name; blexp=yesyes
       
   258 +Cookie: cookie=perhaps; cookie=yes; foobar=name; blexp=yesyes
       
   259  
       
   260  </protocol>
       
   261  </verify>