CVE-2018-1000115: Uncontrolled Resource Consumption (CWE-400)
value: Memcached version 1.5.5 contains an Insufficient Control of Network Message Volume (Network Amplification, CWE-406) vulnerability in the UDP support of the memcached server that can result in denial of service via network flood (traffic amplification of 1:50,000 has been reported by reliable sources). This attack appear to be exploitable via network connectivity to port 11211 UDP. This vulnerability appears to have been fixed in 1.5.6 due to the disabling of the UDP protocol by default.
CWE description: The product does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.
CVSS v3 base score: 7.5
Published: 2018-03-05T14:29Z
Repository: https://github.com/memcached/memcached
Language: Other
Files changed: memcached.c, t/issue_67.t
Commit date: 2018-02-27 10:57:38 -0800
Commit message: disable UDP port by default

As reported, UDP amplification attacks have started to use insecure
internet-exposed memcached instances. UDP used to be a lot more popular as a
transport for memcached many years ago, but I'm not aware of many recent
users.

Ten years ago, the TCP connection overhead from many clients was relatively
high (dozens or hundreds per client server), but these days many clients are
batched, or user fewer processes, or simply anre't worried about it.

While changing the default to listen on localhost only would also help, the
true culprit is UDP. There are many more use cases for using memcached over
the network than there are for using the UDP protocol.

Diff: diff --git a/memcached.c b/memcached.c
index 88a5f2e..7178666 100644
--- a/memcached.c
+++ b/memcached.c
@@ -220,11 +220,11 @@ static void stats_reset(void) {
 
 static void settings_init(void) {
     settings.use_cas = true;
     settings.access = 0700;
     settings.port = 11211;
-    settings.udpport = 11211;
+    settings.udpport = 0;
     /* By default this string should be NULL for getaddrinfo() */
     settings.inter = NULL;
     settings.maxbytes = 64 * 1024 * 1024; /* default is 64MB */
     settings.maxconns = 1024;         /* to limit connections-related memory to about 5MB */
     settings.verbose = 0;
@@ -7477,13 +7477,11 @@ int main (int argc, char **argv) {
                 exit(EX_USAGE);
             }
         }
     }
 
-    if (tcp_specified && settings.port != 0 && !udp_specified) {
-        settings.udpport = settings.port;
-    } else if (udp_specified && settings.udpport != 0 && !tcp_specified) {
+    if (udp_specified && settings.udpport != 0 && !tcp_specified) {
         settings.port = settings.udpport;
     }
 
     if (maxcore != 0) {
         struct rlimit rlim_new;
diff --git a/t/issue_67.t b/t/issue_67.t
index 69c869f..b2d374f 100644
--- a/t/issue_67.t
+++ b/t/issue_67.t
@@ -75,15 +75,15 @@ sub when {
     validate_port($name, $ports{'UDP INET'}, $expected_udp);
 }
 
 # Disabling the defaults since it conflicts with a running instance.
 # when('no arguments', '', 11211, 11211);
-when('specifying tcp port', '-p 11212', 11212, 11212);
+when('specifying tcp port', '-p 11212', 11212, -1);
 when('specifying udp port', '-U 11222', 11222, 11222);
 when('specifying tcp ephemeral port', '-p -1', 0, 0);
 when('specifying udp ephemeral port', '-U -1', 0, 0);
-when('tcp port disabled', '-p 0', -1, 11211);
+when('tcp port disabled', '-p 0', -1, -1);
 when('udp port disabled', '-U 0', 11211, -1);
 when('specifying tcp and udp ports', '-p 11232 -U 11233', 11232, 11233);
 when('specifying tcp and disabling udp', '-p 11242 -U 0', 11242, -1);
 when('specifying udp and disabling tcp', '-p -1 -U 11252', 0, 11252);
 when('specifying tcp and ephemeral udp', '-p 11262 -U -1', 11262, 0);

Vulnerable code:     settings.udpport = 11211;
    if (tcp_specified && settings.port != 0 && !udp_specified) {
        settings.udpport = settings.port;
    } else if (udp_specified && settings.udpport != 0 && !tcp_specified) {
when('specifying tcp port', '-p 11212', 11212, 11212);
when('tcp port disabled', '-p 0', -1, 11211);
Fixed code:     settings.udpport = 0;
    if (udp_specified && settings.udpport != 0 && !tcp_specified) {
when('specifying tcp port', '-p 11212', 11212, -1);
when('tcp port disabled', '-p 0', -1, -1);