summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2021-06-09 17:31:39 +0300
committerOran Agra <oran@redislabs.com>2021-10-04 13:58:43 +0300
commit71be97294abf3657710a044157ebbc8a21489da3 (patch)
tree5ebc16e357444c0f8cd807d3df39bd22babbf8ff
parent34f447f12c28e341d21b2035fcf52f9c05497d45 (diff)
downloadredis-71be97294abf3657710a044157ebbc8a21489da3.tar.gz
Prevent unauthenticated client from easily consuming lots of memory (CVE-2021-32675)
This change sets a low limit for multibulk and bulk length in the protocol for unauthenticated connections, so that they can't easily cause redis to allocate massive amounts of memory by sending just a few characters on the network. The new limits are 10 arguments of 16kb each (instead of 1m of 512mb) (cherry picked from commit 3d221e81f3b680543e34942579af190b049ff283)
-rw-r--r--src/networking.c8
-rw-r--r--tests/unit/auth.tcl16
2 files changed, 24 insertions, 0 deletions
diff --git a/src/networking.c b/src/networking.c
index bfaded9b4..2b8588094 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -1309,6 +1309,10 @@ int processMultibulkBuffer(client *c) {
addReplyError(c,"Protocol error: invalid multibulk length");
setProtocolError("invalid mbulk count",c);
return C_ERR;
+ } else if (ll > 10 && server.requirepass && !c->authenticated) {
+ addReplyError(c, "Protocol error: unauthenticated multibulk length");
+ setProtocolError("unauth mbulk count", c);
+ return C_ERR;
}
c->qb_pos = (newline-c->querybuf)+2;
@@ -1354,6 +1358,10 @@ int processMultibulkBuffer(client *c) {
addReplyError(c,"Protocol error: invalid bulk length");
setProtocolError("invalid bulk length",c);
return C_ERR;
+ } else if (ll > 16384 && server.requirepass && !c->authenticated) {
+ addReplyError(c, "Protocol error: unauthenticated bulk length");
+ setProtocolError("unauth bulk length", c);
+ return C_ERR;
}
c->qb_pos = newline-c->querybuf+2;
diff --git a/tests/unit/auth.tcl b/tests/unit/auth.tcl
index 633cda95c..f5da728e8 100644
--- a/tests/unit/auth.tcl
+++ b/tests/unit/auth.tcl
@@ -24,4 +24,20 @@ start_server {tags {"auth"} overrides {requirepass foobar}} {
r set foo 100
r incr foo
} {101}
+
+ test {For unauthenticated clients multibulk and bulk length are limited} {
+ set rr [redis [srv "host"] [srv "port"] 0]
+ $rr write "*100\r\n"
+ $rr flush
+ catch {[$rr read]} e
+ assert_match {*unauthenticated multibulk length*} $e
+ $rr close
+
+ set rr [redis [srv "host"] [srv "port"] 0]
+ $rr write "*1\r\n\$100000000\r\n"
+ $rr flush
+ catch {[$rr read]} e
+ assert_match {*unauthenticated bulk length*} $e
+ $rr close
+ }
}