I know we (or most of us) are volunteers working on Debian. But I have to admit I'm a bit worried that we haven't patched this critical cache-poisoning vulnerability in Varnish for one month (except in Debian Stretch LTS).

Attached patches containing the fixes for CVE-2022-23959.

For Debian Buster I took them from the Varnish 6.0 LTS branch:

https://github.com/varnishcache/varnish-cache/commit/dcbe8b9ebf5b352e2534fc5645afa1d9747e9647
https://github.com/varnishcache/varnish-cache/commit/b8351f7f6231315f0fe00410b91893235eb29f57

For Debian Bullseye from the Varnish 6.6 branch:

https://github.com/varnishcache/varnish-cache/commit/9ed39d1f796369caafb647fe37b729c07f332327
https://github.com/varnishcache/varnish-cache/commit/ec531e16b9cd139bbf8971c5b306561c669681f4

Cheers,
Andreas
Index: varnish-6.6.1/bin/varnishd/cache/cache_req_body.c
===================================================================
--- varnish-6.6.1.orig/bin/varnishd/cache/cache_req_body.c
+++ varnish-6.6.1/bin/varnishd/cache/cache_req_body.c
@@ -251,6 +251,8 @@ VRB_Ignore(struct req *req)
 	if (req->req_body_status->avail > 0)
 		(void)VRB_Iterate(req->wrk, req->vsl, req,
 		    httpq_req_body_discard, NULL);
+	if (req->req_body_status == BS_ERROR)
+		req->doclose = SC_RX_BODY;
 	return (0);
 }
 
Index: varnish-6.6.1/bin/varnishtest/tests/f00008.vtc
===================================================================
--- /dev/null
+++ varnish-6.6.1/bin/varnishtest/tests/f00008.vtc
@@ -0,0 +1,56 @@
+varnishtest "VRB_Ignore and connection close"
+
+server s1 {
+	rxreq
+	txresp -body HIT
+} -start
+
+varnish v1 -arg "-p timeout_idle=1" -vcl+backend {
+	sub vcl_recv {
+		if (req.url == "/synth") {
+			return (synth(200, "SYNTH"));
+		}
+	}
+} -start
+
+# Prime an object
+client c1 {
+	txreq -url /hit
+	rxresp
+	expect resp.status == 200
+	expect resp.body == HIT
+} -run
+
+# Test synth
+client c2 {
+	txreq -req POST -url /synth -hdr "Content-Length: 2"
+	# Send 1 byte
+	send a
+	# Wait timeout_idle
+	delay 1.1
+	# Send 1 byte
+	send b
+	rxresp
+	expect resp.status == 200
+	expect resp.reason == SYNTH
+	expect resp.http.connection == close
+	timeout 0.5
+	expect_close
+} -run
+
+# Test cache hit
+client c3 {
+	txreq -req GET -url /hit -hdr "Content-Length: 2"
+	# Send 1 byte
+	send a
+	# Wait timeout_idle
+	delay 1.1
+	# Send 1 byte
+	send b
+	rxresp
+	expect resp.status == 200
+	expect resp.body == HIT
+	expect resp.http.connection == close
+	timeout 0.5
+	expect_close
+} -run
Index: varnish-6.1.1/bin/varnishd/cache/cache_req_body.c
===================================================================
--- varnish-6.1.1.orig/bin/varnishd/cache/cache_req_body.c
+++ varnish-6.1.1/bin/varnishd/cache/cache_req_body.c
@@ -247,6 +247,8 @@ VRB_Ignore(struct req *req)
 	if (req->req_body_status == REQ_BODY_WITH_LEN ||
 	    req->req_body_status == REQ_BODY_WITHOUT_LEN)
 		(void)VRB_Iterate(req, httpq_req_body_discard, NULL);
+	if (req->req_body_status == REQ_BODY_FAIL)
+		req->doclose = SC_RX_BODY;
 	return(0);
 }
 
Index: varnish-6.1.1/bin/varnishtest/tests/f00008.vtc
===================================================================
--- /dev/null
+++ varnish-6.1.1/bin/varnishtest/tests/f00008.vtc
@@ -0,0 +1,56 @@
+varnishtest "VRB_Ignore and connection close"
+
+server s1 {
+	rxreq
+	txresp -body HIT
+} -start
+
+varnish v1 -arg "-p timeout_idle=1" -vcl+backend {
+	sub vcl_recv {
+		if (req.url == "/synth") {
+			return (synth(200, "SYNTH"));
+		}
+	}
+} -start
+
+# Prime an object
+client c1 {
+	txreq -url /hit
+	rxresp
+	expect resp.status == 200
+	expect resp.body == HIT
+} -run
+
+# Test synth
+client c2 {
+	txreq -req POST -url /synth -hdr "Content-Length: 2"
+	# Send 1 byte
+	send a
+	# Wait timeout_idle
+	delay 1.1
+	# Send 1 byte
+	send b
+	rxresp
+	expect resp.status == 200
+	expect resp.reason == SYNTH
+	expect resp.http.connection == close
+	timeout 0.5
+	expect_close
+} -run
+
+# Test cache hit
+client c3 {
+	txreq -req GET -url /hit -hdr "Content-Length: 2"
+	# Send 1 byte
+	send a
+	# Wait timeout_idle
+	delay 1.1
+	# Send 1 byte
+	send b
+	rxresp
+	expect resp.status == 200
+	expect resp.body == HIT
+	expect resp.http.connection == close
+	timeout 0.5
+	expect_close
+} -run

Reply via email to