From df6f074520c3671136d1196524717dcaec8bc530 Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Wed, 25 Oct 2023 16:03:13 +0200 Subject: [PATCH 1/6] THREESCALE-10224 CVE-2023-44487 http/2 rapid reset Signed-off-by: Eguzki Astiz Lezaun --- .circleci/config.yml | 2 +- CHANGELOG.md | 4 ++++ Dockerfile | 2 +- Dockerfile.devel | 2 +- Makefile | 6 +++--- docker-compose-devel.yml | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 51d57ba21..0dba7d54a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -105,7 +105,7 @@ executors: openresty: working_directory: /opt/app-root/apicast docker: - - image: quay.io/3scale/apicast-ci:openresty-1.19.3-pr1379 + - image: quay.io/3scale/apicast-ci:openresty-1.19.3-23 - image: redis:3.2.8-alpine environment: TEST_NGINX_BINARY: openresty diff --git a/CHANGELOG.md b/CHANGELOG.md index 0321171e6..938deb6f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed + +- Fixed CVE-2023-44487 (HTTP/2 Rapid Reset) [PR #393](https://github.com/3scale/apicast/pull/392) [THREESCALE-10224](https://issues.redhat.com/browse/THREESCALE-10224) + ### Added - Detect number of CPU shares when running on Cgroups V2 [PR #1410](https://github.com/3scale/apicast/pull/1410) [THREESCALE-10167](https://issues.redhat.com/browse/THREESCALE-10167) diff --git a/Dockerfile b/Dockerfile index aa401be47..6477ee198 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM registry.access.redhat.com/ubi8:8.5 -ARG OPENRESTY_RPM_VERSION="1.19.3-21.el8" +ARG OPENRESTY_RPM_VERSION="1.19.3-23.el8" ARG LUAROCKS_VERSION="2.3.0" ARG JAEGERTRACING_CPP_CLIENT_RPM_VERSION="0.3.1-13.el8" diff --git a/Dockerfile.devel b/Dockerfile.devel index 1a66f8e1c..a15afac47 100644 --- a/Dockerfile.devel +++ b/Dockerfile.devel @@ -1,6 +1,6 @@ FROM registry.access.redhat.com/ubi8:8.5 -ARG OPENRESTY_RPM_VERSION="1.19.3-21.el8" +ARG OPENRESTY_RPM_VERSION="1.19.3-23.el8" ARG LUAROCKS_VERSION="2.3.0" ARG JAEGERTRACING_CPP_CLIENT_RPM_VERSION="0.3.1-13.el8" diff --git a/Makefile b/Makefile index d24d61089..01db96816 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ NPROC ?= $(firstword $(shell nproc 2>/dev/null) 1) SEPARATOR="\n=============================================\n" -DEVEL_IMAGE ?= quay.io/3scale/apicast-ci:openresty-1.19.3-pr1379 +DEVEL_IMAGE ?= quay.io/3scale/apicast-ci:openresty-1.19.3-23 DEVEL_DOCKERFILE ?= Dockerfile.devel RUNTIME_IMAGE ?= quay.io/3scale/apicast:latest @@ -64,9 +64,9 @@ export COMPOSE_PROJECT_NAME # The development image is also used in CI (circleCI) as the 'openresty' executor # When the development image changes, make sure to: # * build a new development image: -# make dev-build IMAGE_NAME=quay.io/3scale/apicast-ci:openresty-1.19.3-pr{NUM} +# make dev-build IMAGE_NAME=quay.io/3scale/apicast-ci:openresty-X.Y.Z-{release_number} # * push to quay.io/3scale/apicast-ci with a fixed tag (avoid floating tags) -# docker push quay.io/3scale/apicast-ci:openresty-1.19.3-pr{NUM} +# docker push quay.io/3scale/apicast-ci:openresty-X.Y.Z-{release_number} # * update .circleci/config.yaml openresty executor with the image URL .PHONY: dev-build dev-build: export OPENRESTY_RPM_VERSION?=1.19.3 diff --git a/docker-compose-devel.yml b/docker-compose-devel.yml index 7a2efe08f..f1f9e927f 100644 --- a/docker-compose-devel.yml +++ b/docker-compose-devel.yml @@ -2,7 +2,7 @@ version: '2.2' services: development: - image: ${IMAGE:-quay.io/3scale/apicast-ci:openresty-1.19.3-pr1379} + image: ${IMAGE:-quay.io/3scale/apicast-ci:openresty-1.19.3-23} platform: "linux/amd64" depends_on: - redis From ed7a3352814cfa641683389eb609a4b1b358ae7f Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Wed, 25 Oct 2023 16:05:48 +0200 Subject: [PATCH 2/6] update changelog with PR number --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 938deb6f9..b0ab10eab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed -- Fixed CVE-2023-44487 (HTTP/2 Rapid Reset) [PR #393](https://github.com/3scale/apicast/pull/392) [THREESCALE-10224](https://issues.redhat.com/browse/THREESCALE-10224) +- Fixed CVE-2023-44487 (HTTP/2 Rapid Reset) [PR #1417](https://github.com/3scale/apicast/pull/1417) [THREESCALE-10224](https://issues.redhat.com/browse/THREESCALE-10224) ### Added From 8143c1d1dffda1bc7ac76d2bd7683a9b93aed875 Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Wed, 25 Oct 2023 16:43:31 +0200 Subject: [PATCH 3/6] codecov: 3% tolerance --- .codecov.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.codecov.yml b/.codecov.yml index f313939e5..947412aa6 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -6,3 +6,14 @@ ignore: - t - bin/busted.lua - examples + +coverage: + status: + project: + default: + target: auto + threshold: 3% + patch: + default: + target: auto + threshold: 3% From 34ec61fc69dd067e5fdbf27fc62232d8e6373f10 Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Tue, 31 Oct 2023 17:00:35 +0100 Subject: [PATCH 4/6] enable lua_check_client_abort Makes HTTP2 reset streams to be accounted and handled by apicast. Ref CVE-2023-44487 --- gateway/conf.d/apicast.conf | 2 ++ .../src/apicast/policy/apicast/apicast.lua | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/gateway/conf.d/apicast.conf b/gateway/conf.d/apicast.conf index ba8d48794..e8a0aa845 100644 --- a/gateway/conf.d/apicast.conf +++ b/gateway/conf.d/apicast.conf @@ -3,6 +3,8 @@ set_by_lua_block $deployment { return require('apicast.user_agent').deployment() } +lua_check_client_abort on; + # TODO: enable in the future when we support SSL # ssl_certificate_by_lua_block { require('apicast.executor').call() } # ssl_session_fetch_by_lua_block { require('apicast.executor').call() } diff --git a/gateway/src/apicast/policy/apicast/apicast.lua b/gateway/src/apicast/policy/apicast/apicast.lua index 0662e5a1d..47b1607f3 100644 --- a/gateway/src/apicast/policy/apicast/apicast.lua +++ b/gateway/src/apicast/policy/apicast/apicast.lua @@ -30,11 +30,17 @@ end function _M.cleanup() -- now abort all the "light threads" running in the current request handler + ngx.log(ngx.INFO, "client closed the (downstream) connection prematurely.") ngx.exit(499) end function _M:rewrite(context) - ngx.on_abort(self.cleanup) + ngx.log(ngx.INFO, "registering on abort") + local ok, err = ngx.on_abort(self.cleanup) + if not ok then + ngx.log(ngx.ERR, "failed to register the on_abort callback: ", err) + ngx.exit(500) + end -- load configuration if not configured -- that is useful when lua_code_cache is off @@ -87,6 +93,13 @@ function _M:post_action(context) end function _M:access(context) + ngx.log(ngx.INFO, "registering on abort") + local ok, err = ngx.on_abort(self.cleanup) + if not ok then + ngx.log(ngx.ERR, "failed to register the on_abort callback: ", err) + ngx.exit(500) + end + if context.skip_apicast_access then return end -- Flag to run post_action() only when access() was executed. @@ -108,6 +121,13 @@ function _M:access(context) end function _M:content(context) + ngx.log(ngx.INFO, "registering on abort") + local ok, err = ngx.on_abort(self.cleanup) + if not ok then + ngx.log(ngx.ERR, "failed to register the on_abort callback: ", err) + ngx.exit(500) + end + if not context[self].upstream then ngx.log(ngx.WARN, "Upstream server not found for this request") return errors.upstream_not_found(context.service) From 02c2ea0f840e6865a6c32c256a96a4560f72651c Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Tue, 31 Oct 2023 17:53:21 +0100 Subject: [PATCH 5/6] remove unnecessary logs --- gateway/src/apicast/policy/apicast/apicast.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/gateway/src/apicast/policy/apicast/apicast.lua b/gateway/src/apicast/policy/apicast/apicast.lua index 47b1607f3..56b59da08 100644 --- a/gateway/src/apicast/policy/apicast/apicast.lua +++ b/gateway/src/apicast/policy/apicast/apicast.lua @@ -35,7 +35,6 @@ function _M.cleanup() end function _M:rewrite(context) - ngx.log(ngx.INFO, "registering on abort") local ok, err = ngx.on_abort(self.cleanup) if not ok then ngx.log(ngx.ERR, "failed to register the on_abort callback: ", err) @@ -93,7 +92,6 @@ function _M:post_action(context) end function _M:access(context) - ngx.log(ngx.INFO, "registering on abort") local ok, err = ngx.on_abort(self.cleanup) if not ok then ngx.log(ngx.ERR, "failed to register the on_abort callback: ", err) @@ -121,7 +119,6 @@ function _M:access(context) end function _M:content(context) - ngx.log(ngx.INFO, "registering on abort") local ok, err = ngx.on_abort(self.cleanup) if not ok then ngx.log(ngx.ERR, "failed to register the on_abort callback: ", err) From 4d1c3e64abfe5f70a644e54feb813cbc01785fad Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Thu, 2 Nov 2023 15:12:18 +0100 Subject: [PATCH 6/6] fix busted tests: spec/policy/apicast/apicast_spec.lua --- spec/policy/apicast/apicast_spec.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/policy/apicast/apicast_spec.lua b/spec/policy/apicast/apicast_spec.lua index 304ae7483..f1ea05310 100644 --- a/spec/policy/apicast/apicast_spec.lua +++ b/spec/policy/apicast/apicast_spec.lua @@ -1,6 +1,16 @@ local _M = require 'apicast.policy.apicast' describe('APIcast policy', function() + local ngx_on_abort_stub + + before_each(function() + -- .access calls ngx.on_abort + -- busted tests are called in the context of ngx.timer + -- and that API ngx.on_abort is disabled in that context. + -- this stub is mocking the call + -- to prevent the internal error: API disabled in the context of ngx.timer + ngx_on_abort_stub = stub(ngx, 'on_abort') + end) it('has a name', function() assert.truthy(_M._NAME)