cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH] Add support for Mozilla's Publix Suffix List

From: Tim Rühsen <tim.ruehsen_at_gmx.de>
Date: Tue, 29 Sep 2015 11:33:01 +0200

Use libpsl to check the domain value of Set-Cookie headers
(and cookie jar entries) for not being a Publix Suffix.

Ref: https://publicsuffix.org/
Ref: https://github.com/publicsuffix/list
Ref: https://github.com/rockdaboot/libpsl

---
 configure.ac            | 14 ++++++++++++
 lib/cookie.c            | 21 +++++++++++++++++
 lib/version.c           |  9 ++++++++
 src/tool_help.c         |  3 +++
 tests/data/Makefile.inc |  1 +
 tests/data/test1136     | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/runtests.pl       | 18 ++++++++++++++-
 7 files changed, 125 insertions(+), 1 deletion(-)
 create mode 100644 tests/data/test1136
diff --git a/configure.ac b/configure.ac
index 26d77eb..771deac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -166,6 +166,7 @@ curl_verbose_msg="enabled (--disable-verbose)"
    curl_rtsp_msg="no      (--enable-rtsp)"
    curl_rtmp_msg="no      (--with-librtmp)"
   curl_mtlnk_msg="no      (--with-libmetalink)"
+    curl_psl_msg="no      (--with-libpsl)"
 
     init_ssl_msg=${curl_ssl_msg}
 
@@ -2314,6 +2315,18 @@ dnl **********************************************************************
 CURL_CHECK_CA_BUNDLE
 
 dnl **********************************************************************
+dnl Check for libpsl
+dnl **********************************************************************
+
+AC_ARG_WITH(libpsl, AS_HELP_STRING([--without-libpsl], [disable support for libpsl cookie checking]), with_libpsl=$withval, with_libpsl=yes)
+if test $with_libpsl != "no"; then
+  AC_SEARCH_LIBS(psl_builtin, psl,
+    [curl_psl_msg="yes"; AC_DEFINE([USE_LIBPSL], [1], [PSL support enabled])],
+    [curl_psl_msg="no      (libpsl not found)"; AC_MSG_WARN(*** libpsl was not found. Supercookie vulnerability possible.)])
+fi
+AM_CONDITIONAL([USE_LIBPSL], [test "$curl_psl_msg" = "yes"])
+
+dnl **********************************************************************
 dnl Check for libmetalink
 dnl **********************************************************************
 
@@ -3741,6 +3754,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
   RTSP support:     ${curl_rtsp_msg}
   RTMP support:     ${curl_rtmp_msg}
   metalink support: ${curl_mtlnk_msg}
+  PSL support:      ${curl_psl_msg}
   HTTP2 support:    ${curl_h2_msg}
   Protocols:        ${SUPPORT_PROTOCOLS}
 ])
diff --git a/lib/cookie.c b/lib/cookie.c
index 22730cf..fc585f5 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -84,6 +84,10 @@ Example set of cookies:
 
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
 
+#ifdef USE_LIBPSL
+# include <libpsl.h>
+#endif
+
 #include "curl_printf.h"
 #include "urldata.h"
 #include "cookie.h"
@@ -379,6 +383,10 @@ Curl_cookie_add(struct SessionHandle *data,
   bool replace_old = FALSE;
   bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
 
+#ifdef USE_LIBPSL
+  const psl_ctx_t *psl;
+#endif
+
 #ifdef CURL_DISABLE_VERBOSE_STRINGS
   (void)data;
 #endif
@@ -777,6 +785,19 @@ Curl_cookie_add(struct SessionHandle *data,
   /* at first, remove expired cookies */
   remove_expired(c);
 
+#ifdef USE_LIBPSL
+  /* Check if the domain is a Public Suffix and if yes, ignore the cookie.
+     This needs a libpsl compiled with builtin data. */
+  if(co->domain && !isip(co->domain) && (psl = psl_builtin()) != NULL) {
+    if(psl_is_public_suffix(psl, co->domain)) {
+      infof("cookie '%s' dropped, domain '%s' is a public suffix\n",
+        co->name, co->domain);
+      freecookie(co);
+      return NULL;
+    }
+  }
+#endif
+
   clist = c->cookies;
   replace_old = FALSE;
   while(clist) {
diff --git a/lib/version.c b/lib/version.c
index 1727c5a..8784c2b 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -40,6 +40,10 @@
 #include <stringprep.h>
 #endif
 
+#ifdef USE_LIBPSL
+#include <libpsl.h>
+#endif
+
 #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
 #include <iconv.h>
 #endif
@@ -100,6 +104,11 @@ char *curl_version(void)
     ptr += len;
   }
 #endif
+#ifdef USE_LIBPSL
+  len = snprintf(ptr, left, " libpsl/%s", psl_get_version());
+  left -= len;
+  ptr += len;
+#endif
 #ifdef USE_WIN32_IDN
   len = snprintf(ptr, left, " WinIDN");
   left -= len;
diff --git a/src/tool_help.c b/src/tool_help.c
index 355fe7d..4f569cd 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -317,6 +317,9 @@ void tool_version_info(void)
 #ifdef USE_METALINK
     printf("Metalink ");
 #endif
+#ifdef USE_LIBPSL
+    printf("PSL ");
+#endif
     puts(""); /* newline */
   }
 }
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index d84b4e2..b053534 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -118,6 +118,7 @@ test1104 test1105 test1106 test1107 test1108 test1109 test1110 test1111 \
 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 \
 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 \
 test1128 test1129 test1130 test1131 test1132 test1133 test1134 test1135 \
+test1136 \
 \
 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
 test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
diff --git a/tests/data/test1136 b/tests/data/test1136
new file mode 100644
index 0000000..16c48b2
--- /dev/null
+++ b/tests/data/test1136
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+cookies
+cookiejar
+PSL
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Content-Type: text/html
+Funny-head: yesyes
+Set-Cookie: test1=forbidden1; domain=example.ck; path=/;
+Set-Cookie: test2=allowed2; domain=www.example.ck; path=/;
+Set-Cookie: test3=forbidden3; domain=ck; path=/;
+Set-Cookie: test4=allowed4; domain=www.ck; path=/;
+Set-Cookie: test5=forbidden5; domain=z-1.compute-1.amazonaws.com; path=/;
+
+boo
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+Check cookies against PSL
+</name>
+<setenv>
+TZ=GMT
+</setenv>
+<command>
+http://www.example.ck/1136 http://www.ck/1136 http://z-1.compute-1.amazonaws.com/1136 -b none -c log/jar1136.txt -x %HOSTIP:%HTTPPORT
+</command>
+
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<file name="log/jar1136.txt" mode="text">
+# Netscape HTTP Cookie File
+# http://curl.haxx.se/docs/http-cookies.html
+# This file was generated by libcurl! Edit at your own risk.
+
+.www.example.ck	TRUE	/	FALSE	0	test2	allowed2
+.www.ck	TRUE	/	FALSE	0	test4	allowed4
+</file>
+</verify>
+</testcase>
diff --git a/tests/runtests.pl b/tests/runtests.pl
index 377d733..6e9f4a1 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -224,6 +224,7 @@ my $has_http2;      # set if libcurl is built with HTTP2 support
 my $has_crypto;     # set if libcurl is built with cryptographic support
 my $has_cares;      # set if built with c-ares
 my $has_threadedres;# set if built with threaded resolver
+my $has_psl;        # set if libcurl is built with PSL support
 
 # this version is decided by the particular nghttp2 library that is being used
 my $h2cver = "h2c";
@@ -2474,6 +2475,10 @@ sub checksystem {
                 # Metalink enabled
                 $has_metalink=1;
             }
+            if($feat =~ /PSL/i) {
+                # PSL enabled
+                $has_psl=1;
+            }
             if($feat =~ /AsynchDNS/i) {
                 if(!$has_cares) {
                     # this means threaded resolver
@@ -2599,8 +2604,9 @@ sub checksystem {
     logmsg sprintf("* HTTP Unix     %s\n", $http_unix?"ON ":"OFF");
     logmsg sprintf("* FTP IPv6      %8s", $ftp_ipv6?"ON ":"OFF");
     logmsg sprintf("  Libtool lib:  %s\n", $libtool?"ON ":"OFF");
-    logmsg sprintf("* Shared build:      %-3s", $has_shared);
+    logmsg sprintf("* PSL:          %8s", $has_psl?"ON ":"OFF");
     logmsg sprintf("  Resolver:     %s\n", $resolver);
+
     if($ssl_version) {
         logmsg sprintf("* SSL library: %13s\n", $ssllib);
     }
@@ -2981,6 +2987,11 @@ sub singletest {
                     next;
                 }
             }
+            elsif($1 eq "PSL") {
+                if($has_psl) {
+                    next;
+                }
+            }
             elsif($1 eq "socks") {
                 next;
             }
@@ -3117,6 +3128,11 @@ sub singletest {
                         next;
                     }
                 }
+                elsif($1 eq "PSL") {
+                    if(!$has_psl) {
+                        next;
+                    }
+                }
                 else {
                     next;
                 }
-- 
2.6.1
--nextPart2814940.PIKxq32GTc
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLQpMaXN0IGFkbWluOiBodHRwOi8vY29vbC5oYXh4LnNlL2xpc3QvbGlzdGluZm8v
Y3VybC1saWJyYXJ5CkV0aXF1ZXR0ZTogIGh0dHA6Ly9jdXJsLmhheHguc2UvbWFpbC9ldGlxdWV0
dGUuaHRtbA==
--nextPart2814940.PIKxq32GTc--
Received on 2001-09-17