diff --git a/SOURCES/0020-prevent-open-redirect-on-refresh-token-requests-rele.patch b/SOURCES/0020-prevent-open-redirect-on-refresh-token-requests-rele.patch
new file mode 100644
index 0000000..4dadc5b
--- /dev/null
+++ b/SOURCES/0020-prevent-open-redirect-on-refresh-token-requests-rele.patch
@@ -0,0 +1,453 @@
+From e4d625b0f1116e50df2737e2738b4c77b35328bb Mon Sep 17 00:00:00 2001
+From: Hans Zandbelt <hans.zandbelt@zmartzone.eu>
+Date: Wed, 10 Jun 2020 18:14:24 +0200
+Subject: [PATCH 1/4] prevent open redirect on refresh token requests; release
+ 2.4.3
+
+add new OIDCRedirectURLsAllowed primitive to handle post logout and
+refresh-return-to validation; addresses #453; closes #466
+
+Signed-off-by: Hans Zandbelt <hans.zandbelt@zmartzone.eu>
+(cherry picked from commit 8ea550f34ce51d8d41ba47843739c964407fa0ad)
+---
+ auth_openidc.conf      |   9 ++
+ src/config.c           |  24 ++++-
+ src/mod_auth_openidc.c | 205 ++++++++++++++++++++++++-----------------
+ src/mod_auth_openidc.h |   1 +
+ src/util.c             |  16 ++--
+ 5 files changed, 166 insertions(+), 89 deletions(-)
+
+diff --git a/auth_openidc.conf b/auth_openidc.conf
+index ce2fba7..87685f6 100644
+--- a/auth_openidc.conf
++++ b/auth_openidc.conf
+@@ -784,3 +784,12 @@
+ # for calculating the fingerprint of the state during authentication.
+ # When not defined the default "both" is used.
+ #OIDCStateInputHeaders [none|user-agent|x-forwarded-for|both]
++
++# Define one or more regular expressions that specify URLs (or domains) allowed for post logout and
++# other redirects such as the "return_to" value on refresh token requests, e.g.:
++#   OIDCRedirectURLsAllowed ^https://www.example.com ^https://(\w+).example.org ^https://example.net/app
++# or:
++#   OIDCRedirectURLsAllowed ^https://www.example.com/logout$ ^https://www.example.com/app/return_to$ 
++# When not defined, the default is to match the hostname in the URL redirected to against
++# the hostname in the current request.
++#OIDCRedirectURLsAllowed [<regexp>]+
+diff --git a/src/config.c b/src/config.c
+index 588e1a3..b2c0da7 100644
+--- a/src/config.c
++++ b/src/config.c
+@@ -264,6 +264,7 @@
+ #define OIDCBlackListedClaims                "OIDCBlackListedClaims"
+ #define OIDCOAuthServerMetadataURL           "OIDCOAuthServerMetadataURL"
+ #define OIDCStateInputHeaders                  "OIDCStateInputHeaders"
++#define OIDCRedirectURLsAllowed                "OIDCRedirectURLsAllowed"
+ 
+ extern module AP_MODULE_DECLARE_DATA auth_openidc_module;
+ 
+@@ -1044,6 +1045,16 @@ static const char * oidc_set_state_input_headers_as(cmd_parms *cmd, void *m,
+ 	return OIDC_CONFIG_DIR_RV(cmd, rv);
+ }
+ 
++static const char * oidc_set_redirect_urls_allowed(cmd_parms *cmd, void *m,
++               const char *arg) {
++    oidc_cfg *cfg = (oidc_cfg *) ap_get_module_config(
++        cmd->server->module_config, &auth_openidc_module);
++    if (cfg->redirect_urls_allowed == NULL)
++        cfg->redirect_urls_allowed = apr_hash_make(cmd->pool);
++    apr_hash_set(cfg->redirect_urls_allowed, arg, APR_HASH_KEY_STRING, arg);
++    return NULL;
++}
++
+ /*
+  * create a new server config record with defaults
+  */
+@@ -1192,6 +1203,8 @@ void *oidc_create_server_config(apr_pool_t *pool, server_rec *svr) {
+ 
+ 	c->state_input_headers = OIDC_DEFAULT_STATE_INPUT_HEADERS;
+ 
++	c->redirect_urls_allowed = NULL;
++
+ 	return c;
+ }
+ 
+@@ -1637,6 +1650,10 @@ void *oidc_merge_server_config(apr_pool_t *pool, void *BASE, void *ADD) {
+ 			add->state_input_headers != OIDC_DEFAULT_STATE_INPUT_HEADERS ?
+ 					add->state_input_headers : base->state_input_headers;
+ 
++	c->redirect_urls_allowed =
++			add->redirect_urls_allowed != NULL ?
++					add->redirect_urls_allowed : base->redirect_urls_allowed;
++
+ 	return c;
+ }
+ 
+@@ -2310,7 +2327,7 @@ void oidc_register_hooks(apr_pool_t *pool) {
+ 	ap_register_auth_provider(pool, AUTHZ_PROVIDER_GROUP,
+ 			OIDC_REQUIRE_CLAIM_NAME, "0", &oidc_authz_claim_provider,
+ 			AP_AUTH_INTERNAL_PER_CONF);
+-#ifdef USE_LIBJQ			
++#ifdef USE_LIBJQ
+ 	ap_register_auth_provider(pool, AUTHZ_PROVIDER_GROUP,
+ 			OIDC_REQUIRE_CLAIMS_EXPR_NAME, "0",
+ 			&oidc_authz_claims_expr_provider, AP_AUTH_INTERNAL_PER_CONF);
+@@ -2891,5 +2908,10 @@ const command_rec oidc_config_cmds[] = {
+ 				NULL,
+ 				RSRC_CONF,
+ 				"Specify header name which is used as the input for calculating the fingerprint of the state during authentication; must be one of \"none\", \"user-agent\", \"x-forwarded-for\" or \"both\" (default)."),
++		AP_INIT_ITERATE(OIDCRedirectURLsAllowed,
++				oidc_set_redirect_urls_allowed,
++				(void *) APR_OFFSETOF(oidc_cfg, redirect_urls_allowed),
++				RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
++				"Specify one or more regular expressions that define URLs allowed for post logout and other redirects."),
+ 		{ NULL }
+ };
+diff --git a/src/mod_auth_openidc.c b/src/mod_auth_openidc.c
+index 68fa2ce..215ed5e 100644
+--- a/src/mod_auth_openidc.c
++++ b/src/mod_auth_openidc.c
+@@ -226,7 +226,8 @@ void oidc_strip_cookies(request_rec *r) {
+ /*
+  * calculates a hash value based on request fingerprint plus a provided nonce string.
+  */
+-static char *oidc_get_browser_state_hash(request_rec *r, oidc_cfg *c, const char *nonce) {
++static char *oidc_get_browser_state_hash(request_rec *r, oidc_cfg *c,
++		const char *nonce) {
+ 
+ 	oidc_debug(r, "enter");
+ 
+@@ -543,14 +544,13 @@ static apr_byte_t oidc_unsolicited_proto_state(request_rec *r, oidc_cfg *c,
+ 	oidc_jose_error_t err;
+ 	oidc_jwk_t *jwk = NULL;
+ 	if (oidc_util_create_symmetric_key(r, c->provider.client_secret,
+-			oidc_alg2keysize(alg), OIDC_JOSE_ALG_SHA256,
+-			TRUE, &jwk) == FALSE)
++			oidc_alg2keysize(alg), OIDC_JOSE_ALG_SHA256, TRUE, &jwk) == FALSE)
+ 		return FALSE;
+ 
+ 	oidc_jwt_t *jwt = NULL;
+ 	if (oidc_jwt_parse(r->pool, state, &jwt,
+-			oidc_util_merge_symmetric_key(r->pool, c->private_keys, jwk),
+-			&err) == FALSE) {
++			oidc_util_merge_symmetric_key(r->pool, c->private_keys, jwk), &err)
++			== FALSE) {
+ 		oidc_error(r,
+ 				"could not parse JWT from state: invalid unsolicited response: %s",
+ 				oidc_jose_e2s(r->pool, err));
+@@ -600,8 +600,7 @@ static apr_byte_t oidc_unsolicited_proto_state(request_rec *r, oidc_cfg *c,
+ 
+ 	char *target_link_uri = NULL;
+ 	oidc_jose_get_string(r->pool, jwt->payload.value.json,
+-			OIDC_CLAIM_TARGET_LINK_URI,
+-			FALSE, &target_link_uri, NULL);
++			OIDC_CLAIM_TARGET_LINK_URI, FALSE, &target_link_uri, NULL);
+ 	if (target_link_uri == NULL) {
+ 		if (c->default_sso_url == NULL) {
+ 			oidc_error(r,
+@@ -1224,8 +1223,8 @@ static apr_byte_t oidc_refresh_access_token(request_rec *r, oidc_cfg *c,
+ 
+ 	/* refresh the tokens by calling the token endpoint */
+ 	if (oidc_proto_refresh_request(r, c, provider, refresh_token, &s_id_token,
+-			&s_access_token, &s_token_type, &expires_in,
+-			&s_refresh_token) == FALSE) {
++			&s_access_token, &s_token_type, &expires_in, &s_refresh_token)
++			== FALSE) {
+ 		oidc_error(r, "access_token could not be refreshed");
+ 		return FALSE;
+ 	}
+@@ -2286,8 +2285,8 @@ static int oidc_discovery(request_rec *r, oidc_cfg *cfg) {
+ 	char *javascript = NULL, *javascript_method = NULL;
+ 	char *html_head =
+ 			"<style type=\"text/css\">body {text-align: center}</style>";
+-	if (oidc_post_preserve_javascript(r, NULL, &javascript,
+-			&javascript_method) == TRUE)
++	if (oidc_post_preserve_javascript(r, NULL, &javascript, &javascript_method)
++			== TRUE)
+ 		html_head = apr_psprintf(r->pool, "%s%s", html_head, javascript);
+ 
+ 	/* now send the HTML contents to the user agent */
+@@ -2531,8 +2530,8 @@ static int oidc_handle_discovery_response(request_rec *r, oidc_cfg *c) {
+ 	}
+ 
+ 	/* do open redirect prevention */
+-	if (oidc_target_link_uri_matches_configuration(r, c,
+-			target_link_uri) == FALSE) {
++	if (oidc_target_link_uri_matches_configuration(r, c, target_link_uri)
++			== FALSE) {
+ 		return oidc_util_html_send_error(r, c->error_template,
+ 				"Invalid Request",
+ 				"\"target_link_uri\" parameter does not match configuration settings, aborting to prevent an open redirect.",
+@@ -2587,7 +2586,8 @@ static int oidc_handle_discovery_response(request_rec *r, oidc_cfg *c) {
+ 		}
+ 
+ 		/* got an account name as input, perform OP discovery with that */
+-		if (oidc_proto_account_based_discovery(r, c, issuer, &issuer) == FALSE) {
++		if (oidc_proto_account_based_discovery(r, c, issuer, &issuer)
++				== FALSE) {
+ 
+ 			/* something did not work out, show a user facing error */
+ 			return oidc_util_html_send_error(r, c->error_template,
+@@ -2687,66 +2687,84 @@ static int oidc_handle_logout_request(request_rec *r, oidc_cfg *c,
+ 	return HTTP_MOVED_TEMPORARILY;
+ }
+ 
+-static apr_byte_t oidc_validate_post_logout_url(request_rec *r, const char *url, char **err_str, char **err_desc) {
+-       apr_uri_t uri;
+-       const char *c_host = NULL;
+-
+-       if (apr_uri_parse(r->pool, url, &uri) != APR_SUCCESS) {
+-               *err_str = apr_pstrdup(r->pool, "Malformed URL");
+-               *err_desc = apr_psprintf(r->pool, "Logout URL malformed: %s", url);
+-               oidc_error(r, "%s: %s", *err_str, *err_desc);
+-               return FALSE;
+-       }
+-
+-       c_host = oidc_get_current_url_host(r);
+-       if ((uri.hostname != NULL)
+-                       && ((strstr(c_host, uri.hostname) == NULL)
+-                                       || (strstr(uri.hostname, c_host) == NULL))) {
+-               *err_str = apr_pstrdup(r->pool, "Invalid Request");
+-               *err_desc =
+-                               apr_psprintf(r->pool,
+-                                               "logout value \"%s\" does not match the hostname of the current request \"%s\"",
+-                                               apr_uri_unparse(r->pool, &uri, 0), c_host);
+-               oidc_error(r, "%s: %s", *err_str, *err_desc);
+-               return FALSE;
+-       } else if ((uri.hostname == NULL) && (strstr(url, "/") != url)) {
+-               *err_str = apr_pstrdup(r->pool, "Malformed URL");
+-               *err_desc =
+-                               apr_psprintf(r->pool,
+-                                               "No hostname was parsed and it does not seem to be relative, i.e starting with '/': %s",
+-                                               url);
+-               oidc_error(r, "%s: %s", *err_str, *err_desc);
+-               return FALSE;
+-        } else if ((uri.hostname == NULL) && (strstr(url, "//") == url)) {
+-                *err_str = apr_pstrdup(r->pool, "Malformed URL");
+-                *err_desc =
+-                                apr_psprintf(r->pool,
+-                                                "No hostname was parsed and starting with '//': %s",
+-                                                url);
+-                oidc_error(r, "%s: %s", *err_str, *err_desc);
+-                return FALSE;
+-        } else if ((uri.hostname == NULL) && (strstr(url, "/\\") == url)) {
+-                *err_str = apr_pstrdup(r->pool, "Malformed URL");
+-                *err_desc =
+-                                apr_psprintf(r->pool,
+-                                                "No hostname was parsed and starting with '/\\': %s",
+-                                                url);
+-                oidc_error(r, "%s: %s", *err_str, *err_desc);
+-                return FALSE;
+-       }
+-
+-       /* validate the URL to prevent HTTP header splitting */
+-       if (((strstr(url, "\n") != NULL) || strstr(url, "\r") != NULL)) {
+-               *err_str = apr_pstrdup(r->pool, "Invalid Request");
+-               *err_desc =
+-                               apr_psprintf(r->pool,
+-                                               "logout value \"%s\" contains illegal \"\n\" or \"\r\" character(s)",
+-                                               url);
+-               oidc_error(r, "%s: %s", *err_str, *err_desc);
+-               return FALSE;
+-       }
+-
+-       return TRUE;
++static apr_byte_t oidc_validate_redirect_url(request_rec *r, oidc_cfg *c,
++		const char *url, char **err_str, char **err_desc) {
++	apr_uri_t uri;
++	const char *c_host = NULL;
++	apr_hash_index_t *hi = NULL;
++
++	if (apr_uri_parse(r->pool, url, &uri) != APR_SUCCESS) {
++		*err_str = apr_pstrdup(r->pool, "Malformed URL");
++		*err_desc = apr_psprintf(r->pool, "not a valid URL value: %s", url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	}
++
++	if (c->redirect_urls_allowed != NULL) {
++		for (hi = apr_hash_first(NULL, c->redirect_urls_allowed); hi; hi =
++				apr_hash_next(hi)) {
++			apr_hash_this(hi, (const void**) &c_host, NULL, NULL);
++			if (oidc_util_regexp_first_match(r->pool, url, c_host,
++					NULL, err_str) == TRUE)
++				break;
++		}
++		if (hi == NULL) {
++			*err_str = apr_pstrdup(r->pool, "URL not allowed");
++			*err_desc =
++					apr_psprintf(r->pool,
++							"value does not match the list of allowed redirect URLs: %s",
++							url);
++			oidc_error(r, "%s: %s", *err_str, *err_desc);
++			return FALSE;
++		}
++	} else if (uri.hostname != NULL) {
++		c_host = oidc_get_current_url_host(r);
++		if ((strstr(c_host, uri.hostname) == NULL)
++				|| (strstr(uri.hostname, c_host) == NULL)) {
++			*err_str = apr_pstrdup(r->pool, "Invalid Request");
++			*err_desc =
++					apr_psprintf(r->pool,
++							"URL value \"%s\" does not match the hostname of the current request \"%s\"",
++							apr_uri_unparse(r->pool, &uri, 0), c_host);
++			oidc_error(r, "%s: %s", *err_str, *err_desc);
++			return FALSE;
++		}
++	}
++
++	if ((uri.hostname == NULL) && (strstr(url, "/") != url)) {
++		*err_str = apr_pstrdup(r->pool, "Malformed URL");
++		*err_desc =
++				apr_psprintf(r->pool,
++						"No hostname was parsed and it does not seem to be relative, i.e starting with '/': %s",
++						url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	} else if ((uri.hostname == NULL) && (strstr(url, "//") == url)) {
++		*err_str = apr_pstrdup(r->pool, "Malformed URL");
++		*err_desc = apr_psprintf(r->pool,
++				"No hostname was parsed and starting with '//': %s", url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	} else if ((uri.hostname == NULL) && (strstr(url, "/\\") == url)) {
++		*err_str = apr_pstrdup(r->pool, "Malformed URL");
++		*err_desc = apr_psprintf(r->pool,
++				"No hostname was parsed and starting with '/\\': %s", url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	}
++
++	/* validate the URL to prevent HTTP header splitting */
++	if (((strstr(url, "\n") != NULL) || strstr(url, "\r") != NULL)) {
++		*err_str = apr_pstrdup(r->pool, "Invalid URL");
++		*err_desc =
++				apr_psprintf(r->pool,
++						"URL value \"%s\" contains illegal \"\n\" or \"\r\" character(s)",
++						url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	}
++
++    return TRUE;
+ }
+ 
+ /*
+@@ -2774,12 +2792,11 @@ static int oidc_handle_logout(request_rec *r, oidc_cfg *c,
+ 	} else {
+ 
+ 		/* do input validation on the logout parameter value */
+-
+-		if (oidc_validate_post_logout_url(r, url, &error_str,
+-			&error_description) == FALSE) {
+-		return oidc_util_html_send_error(r, c->error_template, error_str,
+-			error_description,
+-			HTTP_BAD_REQUEST); 
++		if (oidc_validate_redirect_url(r, c, url, &error_str,
++				&error_description) == FALSE) {
++			return oidc_util_html_send_error(r, c->error_template, error_str,
++					error_description,
++					HTTP_BAD_REQUEST);
+ 		}
+ 	}
+ 
+@@ -3027,6 +3044,8 @@ static int oidc_handle_refresh_token_request(request_rec *r, oidc_cfg *c,
+ 	char *return_to = NULL;
+ 	char *r_access_token = NULL;
+ 	char *error_code = NULL;
++	char *error_str = NULL;
++	char *error_description = NULL;
+ 
+ 	/* get the command passed to the session management handler */
+ 	oidc_util_get_request_parameter(r, OIDC_REDIRECT_URI_REQUEST_REFRESH,
+@@ -3041,6 +3060,14 @@ static int oidc_handle_refresh_token_request(request_rec *r, oidc_cfg *c,
+ 		return HTTP_INTERNAL_SERVER_ERROR;
+ 	}
+ 
++	/* do input validation on the return to parameter value */
++	if (oidc_validate_redirect_url(r, c, return_to, &error_str,
++			&error_description) == FALSE) {
++		oidc_error(r, "return_to URL validation failed: %s: %s", error_str,
++				error_description);
++		return HTTP_INTERNAL_SERVER_ERROR;
++	}
++
+ 	if (r_access_token == NULL) {
+ 		oidc_error(r,
+ 				"refresh token request handler called with no access_token parameter");
+@@ -3201,8 +3228,8 @@ static int oidc_handle_info_request(request_rec *r, oidc_cfg *c,
+ 
+ 				/* get the current provider info */
+ 				oidc_provider_t *provider = NULL;
+-				if (oidc_get_provider_from_session(r, c, session,
+-						&provider) == FALSE)
++				if (oidc_get_provider_from_session(r, c, session, &provider)
++						== FALSE)
+ 					return HTTP_INTERNAL_SERVER_ERROR;
+ 
+ 				/* execute the actual refresh grant */
+@@ -3319,6 +3346,20 @@ int oidc_handle_redirect_uri_request(request_rec *r, oidc_cfg *c,
+ 		/* this is an authorization response from the OP using the Basic Client profile or a Hybrid flow*/
+ 		return oidc_handle_redirect_authorization_response(r, c, session);
+ 
++		/*
++		 *
++		 * Note that we are checking for logout *before* checking for a POST authorization response
++		 * to handle backchannel POST-based logout
++		 *
++		 * so any POST to the Redirect URI that does not have a logout query parameter will be handled
++		 * as an authorization response; alternatively we could assume that a POST response has no
++		 * parameters
++		 */
++	} else if (oidc_util_request_has_parameter(r,
++			OIDC_REDIRECT_URI_REQUEST_LOGOUT)) {
++		/* handle logout */
++		return oidc_handle_logout(r, c, session);
++
+ 	} else if (oidc_proto_is_post_authorization_response(r, c)) {
+ 
+ 		/* this is an authorization response using the fragment(+POST) response_mode with the Implicit Client profile */
+diff --git a/src/mod_auth_openidc.h b/src/mod_auth_openidc.h
+index 6821d0c..ea79e6b 100644
+--- a/src/mod_auth_openidc.h
++++ b/src/mod_auth_openidc.h
+@@ -414,6 +414,7 @@ typedef struct oidc_cfg {
+ 
+ 	apr_byte_t state_input_headers;
+ 
++	apr_hash_t *redirect_urls_allowed;
+ } oidc_cfg;
+ 
+ int oidc_check_user_id(request_rec *r);
+diff --git a/src/util.c b/src/util.c
+index c1fa5f3..4b4e16b 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -2201,14 +2201,18 @@ apr_byte_t oidc_util_regexp_first_match(apr_pool_t *pool, const char *input,
+ 		goto out;
+ 	}
+ 
+-	if (pcre_get_substring(input, subStr, rc, OIDC_UTIL_REGEXP_MATCH_NR,
+-			&(psubStrMatchStr)) <= 0) {
+-		*error_str = apr_psprintf(pool, "pcre_get_substring failed (rc=%d)",
+-				rc);
+-		goto out;
++	if (output) {
++
++		if (pcre_get_substring(input, subStr, rc, OIDC_UTIL_REGEXP_MATCH_NR,
++				&(psubStrMatchStr)) <= 0) {
++			*error_str = apr_psprintf(pool, "pcre_get_substring failed (rc=%d)",
++					rc);
++			goto out;
++		}
++
++		*output = apr_pstrdup(pool, psubStrMatchStr);
+ 	}
+ 
+-	*output = apr_pstrdup(pool, psubStrMatchStr);
+ 	rv = TRUE;
+ 
+ out:
+-- 
+2.31.1
+
diff --git a/SOURCES/0021-prevent-XSS-and-open-redirect-on-OIDC-session-manage.patch b/SOURCES/0021-prevent-XSS-and-open-redirect-on-OIDC-session-manage.patch
new file mode 100644
index 0000000..f1da3a4
--- /dev/null
+++ b/SOURCES/0021-prevent-XSS-and-open-redirect-on-OIDC-session-manage.patch
@@ -0,0 +1,167 @@
+From a1b8e7aa92e5e624a5f90bb736c307dae22230a1 Mon Sep 17 00:00:00 2001
+From: Hans Zandbelt <hans.zandbelt@zmartzone.eu>
+Date: Mon, 27 Jul 2020 19:35:29 +0200
+Subject: [PATCH 2/4] prevent XSS and open redirect on OIDC session
+ managemement OP iframe
+
+- apply OIDCRedirectURLsAllowed on the login_uri parameter
+- thanks Andrew Brady
+- bump to 2.4.4rc3
+
+Signed-off-by: Hans Zandbelt <hans.zandbelt@zmartzone.eu>
+(cherry picked from commit 51d997899afea6ea454abda49bd4cd41aa7c0cdc)
+---
+ ChangeLog              | 12 ++++++------
+ auth_openidc.conf      |  3 ++-
+ configure.ac           |  2 +-
+ src/mod_auth_openidc.c | 21 +++++++++++++++++----
+ 4 files changed, 26 insertions(+), 12 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index eba2ebc..075f98d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -86,7 +86,7 @@
+ - bump to 2.3.5rc0
+ 
+ 04/27/2018
+-- avoid crash when a relative logout URL parameter is passed in; thanks Vivien Delenne 
++- avoid crash when a relative logout URL parameter is passed in; thanks Vivien Delenne
+ - release 2.3.4
+ 
+ 03/22/2018
+@@ -258,7 +258,7 @@
+ - bump to 2.2.1rc6
+ 
+ 05/18/2017
+-- fix parse function of OIDCRequestObject configuration option; thanks @suttod 
++- fix parse function of OIDCRequestObject configuration option; thanks @suttod
+ 
+ 05/17/2017
+ - avoid crash when the X-Forwarded-Proto header is not correctly set by a reverse proxy in front of mod_auth_openidc
+@@ -325,7 +325,7 @@
+ 
+ 02/20/2017
+ - security fix: scrub headers for "AuthType oauth20"
+-- release 2.1.6 
++- release 2.1.6
+ 
+ 02/15/2017
+ - improve logging of session max duration and session inactivity timeout
+@@ -534,7 +534,7 @@
+ - bump to 1.9.0rc3
+ 
+ 7/19/2016
+-- add support for chunked session cookies; closes #153; thanks @glatzert 
++- add support for chunked session cookies; closes #153; thanks @glatzert
+ - bump to 1.9.0rc2
+ 
+ 7/9/2016
+@@ -911,7 +911,7 @@
+ 
+ 1/1/2015
+ - update copyright to 2015
+-- use json_int_t (seconds) for "exp" and "iat" fields, instead of apr_time_t (microseconds) 
++- use json_int_t (seconds) for "exp" and "iat" fields, instead of apr_time_t (microseconds)
+ - correct expiry debug printout
+ - bump to 1.7.2rc1
+ 
+@@ -1191,7 +1191,7 @@
+ - support using a Bearer token on client registration calls
+ 
+ 4/22/2014
+-- match request and response type 
++- match request and response type
+ - check at_hash value on "token id_token" implicit flow
+ - use shared memory caching by default
+ - release 1.2
+diff --git a/auth_openidc.conf b/auth_openidc.conf
+index 87685f6..75cdb8e 100644
+--- a/auth_openidc.conf
++++ b/auth_openidc.conf
+@@ -786,7 +786,8 @@
+ #OIDCStateInputHeaders [none|user-agent|x-forwarded-for|both]
+ 
+ # Define one or more regular expressions that specify URLs (or domains) allowed for post logout and
+-# other redirects such as the "return_to" value on refresh token requests, e.g.:
++# other redirects such as the "return_to" value on refresh token requests, and the "login_uri" value
++# on session management based logins through the OP iframe, e.g.:
+ #   OIDCRedirectURLsAllowed ^https://www.example.com ^https://(\w+).example.org ^https://example.net/app
+ # or:
+ #   OIDCRedirectURLsAllowed ^https://www.example.com/logout$ ^https://www.example.com/app/return_to$ 
+diff --git a/configure.ac b/configure.ac
+index ad5ba0e..c61d117 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -91,7 +91,7 @@ HAVE_LIBJQ=0
+ 
+ AC_ARG_WITH(jq,
+         [  --with-jq=PATH          location of your libjq installation])
+-    
++
+ if test -n "$with_jq"
+ then
+     JQ_CFLAGS="-I$with_jq/include"
+diff --git a/src/mod_auth_openidc.c b/src/mod_auth_openidc.c
+index 215ed5e..68fbca5 100644
+--- a/src/mod_auth_openidc.c
++++ b/src/mod_auth_openidc.c
+@@ -2688,7 +2688,8 @@ static int oidc_handle_logout_request(request_rec *r, oidc_cfg *c,
+ }
+ 
+ static apr_byte_t oidc_validate_redirect_url(request_rec *r, oidc_cfg *c,
+-		const char *url, char **err_str, char **err_desc) {
++		const char *url, apr_byte_t restrict_to_host, char **err_str,
++		char **err_desc) {
+ 	apr_uri_t uri;
+ 	const char *c_host = NULL;
+ 	apr_hash_index_t *hi = NULL;
+@@ -2717,7 +2718,7 @@ static apr_byte_t oidc_validate_redirect_url(request_rec *r, oidc_cfg *c,
+ 			oidc_error(r, "%s: %s", *err_str, *err_desc);
+ 			return FALSE;
+ 		}
+-	} else if (uri.hostname != NULL) {
++	} else if ((uri.hostname != NULL) && (restrict_to_host == TRUE)) {
+ 		c_host = oidc_get_current_url_host(r);
+ 		if ((strstr(c_host, uri.hostname) == NULL)
+ 				|| (strstr(uri.hostname, c_host) == NULL)) {
+@@ -2792,7 +2793,7 @@ static int oidc_handle_logout(request_rec *r, oidc_cfg *c,
+ 	} else {
+ 
+ 		/* do input validation on the logout parameter value */
+-		if (oidc_validate_redirect_url(r, c, url, &error_str,
++		if (oidc_validate_redirect_url(r, c, url, TRUE, &error_str,
+ 				&error_description) == FALSE) {
+ 			return oidc_util_html_send_error(r, c->error_template, error_str,
+ 					error_description,
+@@ -2948,6 +2949,18 @@ static int oidc_handle_session_management_iframe_rp(request_rec *r, oidc_cfg *c,
+ 	if (s_poll_interval == NULL)
+ 		s_poll_interval = "3000";
+ 
++	int poll_interval = s_poll_interval ? strtol(s_poll_interval, NULL, 10) : 0;
++	if ((poll_interval <= 0) || (poll_interval > 3600 * 24))
++		poll_interval = 3000;
++
++	char *login_uri = NULL, *error_str = NULL, *error_description = NULL;
++	oidc_util_get_request_parameter(r, "login_uri", &login_uri);
++	if ((login_uri != NULL)
++			&& (oidc_validate_redirect_url(r, c, login_uri, FALSE, &error_str,
++					&error_description) == FALSE)) {
++		return HTTP_BAD_REQUEST;
++	}
++
+ 	const char *redirect_uri = oidc_get_redirect_uri(r, c);
+ 	java_script = apr_psprintf(r->pool, java_script, origin, client_id,
+ 			session_state, op_iframe_id, s_poll_interval, redirect_uri,
+@@ -3061,7 +3074,7 @@ static int oidc_handle_refresh_token_request(request_rec *r, oidc_cfg *c,
+ 	}
+ 
+ 	/* do input validation on the return to parameter value */
+-	if (oidc_validate_redirect_url(r, c, return_to, &error_str,
++	if (oidc_validate_redirect_url(r, c, return_to, TRUE, &error_str,
+ 			&error_description) == FALSE) {
+ 		oidc_error(r, "return_to URL validation failed: %s: %s", error_str,
+ 				error_description);
+-- 
+2.31.1
+
diff --git a/SOURCES/0022-replace-potentially-harmful-backslashes-with-forward.patch b/SOURCES/0022-replace-potentially-harmful-backslashes-with-forward.patch
new file mode 100644
index 0000000..170e275
--- /dev/null
+++ b/SOURCES/0022-replace-potentially-harmful-backslashes-with-forward.patch
@@ -0,0 +1,42 @@
+From 466f470265554e0e3ae27a6d82375456d2c133e6 Mon Sep 17 00:00:00 2001
+From: Hans Zandbelt <hans.zandbelt@zmartzone.eu>
+Date: Thu, 22 Jul 2021 15:32:12 +0200
+Subject: [PATCH 3/4] replace potentially harmful backslashes with forward
+ slashes when validating redirection URLs
+
+(cherry picked from commit 69cb206225c749b51db980d44dc268eee5623f2b)
+---
+ src/mod_auth_openidc.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/src/mod_auth_openidc.c b/src/mod_auth_openidc.c
+index 68fbca5..c96af75 100644
+--- a/src/mod_auth_openidc.c
++++ b/src/mod_auth_openidc.c
+@@ -2687,12 +2687,22 @@ static int oidc_handle_logout_request(request_rec *r, oidc_cfg *c,
+ 	return HTTP_MOVED_TEMPORARILY;
+ }
+ 
++
++#define OIDC_MAX_URL_LENGTH DEFAULT_LIMIT_REQUEST_LINE * 2
++
+ static apr_byte_t oidc_validate_redirect_url(request_rec *r, oidc_cfg *c,
+-		const char *url, apr_byte_t restrict_to_host, char **err_str,
++		const char *redirect_to_url, apr_byte_t restrict_to_host, char **err_str,
+ 		char **err_desc) {
+ 	apr_uri_t uri;
+ 	const char *c_host = NULL;
+ 	apr_hash_index_t *hi = NULL;
++	size_t i = 0;
++	char *url = apr_pstrndup(r->pool, redirect_to_url, OIDC_MAX_URL_LENGTH);
++
++	// replace potentially harmful backslashes with forward slashes
++	for (i = 0; i < strlen(url); i++)
++		if (url[i] == '\\')
++			url[i] = '/';
+ 
+ 	if (apr_uri_parse(r->pool, url, &uri) != APR_SUCCESS) {
+ 		*err_str = apr_pstrdup(r->pool, "Malformed URL");
+-- 
+2.31.1
+
diff --git a/SOURCES/0023-apply-OIDCRedirectURLsAllowed-setting-to-target_link.patch b/SOURCES/0023-apply-OIDCRedirectURLsAllowed-setting-to-target_link.patch
new file mode 100644
index 0000000..24d6b1e
--- /dev/null
+++ b/SOURCES/0023-apply-OIDCRedirectURLsAllowed-setting-to-target_link.patch
@@ -0,0 +1,306 @@
+From eac10ec54971ff021113f96c80deab9991faafc4 Mon Sep 17 00:00:00 2001
+From: Hans Zandbelt <hans.zandbelt@zmartzone.eu>
+Date: Fri, 3 Sep 2021 10:41:21 +0200
+Subject: [PATCH 4/4] apply OIDCRedirectURLsAllowed setting to target_link_uri
+
+closes #672; thanks @Meheni
+release 2.4.9.4
+
+Signed-off-by: Hans Zandbelt <hans.zandbelt@zmartzone.eu>
+(cherry picked from commit 03e6bfb446f4e3f27c003d30d6a433e5dd8e2b3d)
+---
+ AUTHORS                |  31 +++++++
+ auth_openidc.conf      |   5 +-
+ src/mod_auth_openidc.c | 193 +++++++++++++++++++++--------------------
+ 3 files changed, 135 insertions(+), 94 deletions(-)
+
+diff --git a/AUTHORS b/AUTHORS
+index 1d91449..4f77eab 100644
+--- a/AUTHORS
++++ b/AUTHORS
+@@ -46,3 +46,34 @@ reporting bugs, providing fixes, suggesting useful features or other:
+ 	timpuri <https://github.com/timpuri>
+ 	Eldar Zaitov <https://github.com/kyprizel>
+ 	Gergan Penkov <https://github.com/gergan>
++	Florian Weimer <https://github.com/fweimer>
++	Aaron Donovan <https://github.com/amdonov>
++	Hans Petter Bieker <https://github.com/hpbieker>
++	archzone <https://github.com/archzone>
++	Petteri Stenius <https://github.com/psteniusubi>
++	Lance Fannin <lancekf08@gmail.com>
++	Ricardo Martin Camarero <https://github.com/rickyepoderi>
++	Filip Vujicic <https://github.com/FilipVujicic>
++	Janusz Ulanowski <https://github.com/janul>
++	Aimoto Norihito <https://github.com/oss-aimoto>
++	Andy Lindeman <https://github.com/alindeman>
++	Stefan Wachter <https://github.com/swachter>
++	Paolo Battino
++	absynth76 <https://github.com/absynth76>
++	Aaron Jones <https://github.com/wwaaron>
++	Bryan Ingram <https://github/bcingram>
++	Tim Deisser <https://github.com/deisser>
++	Peter Hurtenbach <https://github.com/Peter0x48>
++	Paul Spangler <https://github.com/spanglerco>
++	Chris Pawling <https://github.com/chris468>
++	Matthias Fleschütz <https://github.com/blindzero>
++	Harri Rautila <https://github.com/hrautila>
++	Tatsuhiko Yasumatsu <https://github.com/ty60>
++	Adam Stadler <https://github.com/tzfx>
++	Steffen Greber <https://github.com/codemaker219>
++	Iain Heggie <https://github.com/iainh>
++	Dirk Kok <https://github.com/Foxite>
++	Meheni https://github.com/Meheni
++
++
++
+diff --git a/auth_openidc.conf b/auth_openidc.conf
+index 75cdb8e..55febe5 100644
+--- a/auth_openidc.conf
++++ b/auth_openidc.conf
+@@ -786,8 +786,9 @@
+ #OIDCStateInputHeaders [none|user-agent|x-forwarded-for|both]
+ 
+ # Define one or more regular expressions that specify URLs (or domains) allowed for post logout and
+-# other redirects such as the "return_to" value on refresh token requests, and the "login_uri" value
+-# on session management based logins through the OP iframe, e.g.:
++# other redirects such as the "return_to" value on refresh token requests, the "login_uri" value
++# on session management based logins through the OP iframe, and the "target_link_uri" parameter in
++# 3rd-party initiated logins, e.g.:
+ #   OIDCRedirectURLsAllowed ^https://www.example.com ^https://(\w+).example.org ^https://example.net/app
+ # or:
+ #   OIDCRedirectURLsAllowed ^https://www.example.com/logout$ ^https://www.example.com/app/return_to$ 
+diff --git a/src/mod_auth_openidc.c b/src/mod_auth_openidc.c
+index c96af75..4cc7976 100644
+--- a/src/mod_auth_openidc.c
++++ b/src/mod_auth_openidc.c
+@@ -2476,6 +2476,96 @@ static int oidc_target_link_uri_matches_configuration(request_rec *r,
+ 	return TRUE;
+ }
+ 
++#define OIDC_MAX_URL_LENGTH 8192 * 2
++
++static apr_byte_t oidc_validate_redirect_url(request_rec *r, oidc_cfg *c,
++		const char *redirect_to_url, apr_byte_t restrict_to_host, char **err_str,
++		char **err_desc) {
++	apr_uri_t uri;
++	const char *c_host = NULL;
++	apr_hash_index_t *hi = NULL;
++	size_t i = 0;
++	char *url = apr_pstrndup(r->pool, redirect_to_url, OIDC_MAX_URL_LENGTH);
++
++	// replace potentially harmful backslashes with forward slashes
++	for (i = 0; i < strlen(url); i++)
++		if (url[i] == '\\')
++			url[i] = '/';
++
++	if (apr_uri_parse(r->pool, url, &uri) != APR_SUCCESS) {
++		*err_str = apr_pstrdup(r->pool, "Malformed URL");
++		*err_desc = apr_psprintf(r->pool, "not a valid URL value: %s", url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	}
++
++	if (c->redirect_urls_allowed != NULL) {
++		for (hi = apr_hash_first(NULL, c->redirect_urls_allowed); hi; hi =
++				apr_hash_next(hi)) {
++			apr_hash_this(hi, (const void**) &c_host, NULL, NULL);
++			if (oidc_util_regexp_first_match(r->pool, url, c_host,
++					NULL, err_str) == TRUE)
++				break;
++		}
++		if (hi == NULL) {
++			*err_str = apr_pstrdup(r->pool, "URL not allowed");
++			*err_desc =
++					apr_psprintf(r->pool,
++							"value does not match the list of allowed redirect URLs: %s",
++							url);
++			oidc_error(r, "%s: %s", *err_str, *err_desc);
++			return FALSE;
++		}
++	} else if ((uri.hostname != NULL) && (restrict_to_host == TRUE)) {
++		c_host = oidc_get_current_url_host(r);
++		if ((strstr(c_host, uri.hostname) == NULL)
++				|| (strstr(uri.hostname, c_host) == NULL)) {
++			*err_str = apr_pstrdup(r->pool, "Invalid Request");
++			*err_desc =
++					apr_psprintf(r->pool,
++							"URL value \"%s\" does not match the hostname of the current request \"%s\"",
++							apr_uri_unparse(r->pool, &uri, 0), c_host);
++			oidc_error(r, "%s: %s", *err_str, *err_desc);
++			return FALSE;
++		}
++	}
++
++	if ((uri.hostname == NULL) && (strstr(url, "/") != url)) {
++		*err_str = apr_pstrdup(r->pool, "Malformed URL");
++		*err_desc =
++				apr_psprintf(r->pool,
++						"No hostname was parsed and it does not seem to be relative, i.e starting with '/': %s",
++						url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	} else if ((uri.hostname == NULL) && (strstr(url, "//") == url)) {
++		*err_str = apr_pstrdup(r->pool, "Malformed URL");
++		*err_desc = apr_psprintf(r->pool,
++				"No hostname was parsed and starting with '//': %s", url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	} else if ((uri.hostname == NULL) && (strstr(url, "/\\") == url)) {
++		*err_str = apr_pstrdup(r->pool, "Malformed URL");
++		*err_desc = apr_psprintf(r->pool,
++				"No hostname was parsed and starting with '/\\': %s", url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	}
++
++	/* validate the URL to prevent HTTP header splitting */
++	if (((strstr(url, "\n") != NULL) || strstr(url, "\r") != NULL)) {
++		*err_str = apr_pstrdup(r->pool, "Invalid URL");
++		*err_desc =
++				apr_psprintf(r->pool,
++						"URL value \"%s\" contains illegal \"\n\" or \"\r\" character(s)",
++						url);
++		oidc_error(r, "%s: %s", *err_str, *err_desc);
++		return FALSE;
++	}
++
++	return TRUE;
++}
++
+ /*
+  * handle a response from an IDP discovery page and/or handle 3rd-party initiated SSO
+  */
+@@ -2486,6 +2576,8 @@ static int oidc_handle_discovery_response(request_rec *r, oidc_cfg *c) {
+ 			*auth_request_params = NULL, *csrf_cookie, *csrf_query = NULL,
+ 			*user = NULL, *path_scopes;
+ 	oidc_provider_t *provider = NULL;
++	char *error_str = NULL;
++	char *error_description = NULL;
+ 
+ 	oidc_util_get_request_parameter(r, OIDC_DISC_OP_PARAM, &issuer);
+ 	oidc_util_get_request_parameter(r, OIDC_DISC_USER_PARAM, &user);
+@@ -2529,7 +2621,7 @@ static int oidc_handle_discovery_response(request_rec *r, oidc_cfg *c) {
+ 		target_link_uri = c->default_sso_url;
+ 	}
+ 
+-	/* do open redirect prevention */
++	/* do open redirect prevention, step 1 */
+ 	if (oidc_target_link_uri_matches_configuration(r, c, target_link_uri)
+ 			== FALSE) {
+ 		return oidc_util_html_send_error(r, c->error_template,
+@@ -2538,6 +2630,14 @@ static int oidc_handle_discovery_response(request_rec *r, oidc_cfg *c) {
+ 				HTTP_UNAUTHORIZED);
+ 	}
+ 
++	/* do input validation on the target_link_uri parameter value, step 2 */
++	if (oidc_validate_redirect_url(r, c, target_link_uri, TRUE, &error_str,
++			&error_description) == FALSE) {
++		return oidc_util_html_send_error(r, c->error_template, error_str,
++				error_description,
++				HTTP_UNAUTHORIZED);
++	}
++
+ 	/* see if this is a static setup */
+ 	if (c->metadata_dir == NULL) {
+ 		if ((oidc_provider_static_config(r, c, &provider) == TRUE)
+@@ -2687,97 +2787,6 @@ static int oidc_handle_logout_request(request_rec *r, oidc_cfg *c,
+ 	return HTTP_MOVED_TEMPORARILY;
+ }
+ 
+-
+-#define OIDC_MAX_URL_LENGTH DEFAULT_LIMIT_REQUEST_LINE * 2
+-
+-static apr_byte_t oidc_validate_redirect_url(request_rec *r, oidc_cfg *c,
+-		const char *redirect_to_url, apr_byte_t restrict_to_host, char **err_str,
+-		char **err_desc) {
+-	apr_uri_t uri;
+-	const char *c_host = NULL;
+-	apr_hash_index_t *hi = NULL;
+-	size_t i = 0;
+-	char *url = apr_pstrndup(r->pool, redirect_to_url, OIDC_MAX_URL_LENGTH);
+-
+-	// replace potentially harmful backslashes with forward slashes
+-	for (i = 0; i < strlen(url); i++)
+-		if (url[i] == '\\')
+-			url[i] = '/';
+-
+-	if (apr_uri_parse(r->pool, url, &uri) != APR_SUCCESS) {
+-		*err_str = apr_pstrdup(r->pool, "Malformed URL");
+-		*err_desc = apr_psprintf(r->pool, "not a valid URL value: %s", url);
+-		oidc_error(r, "%s: %s", *err_str, *err_desc);
+-		return FALSE;
+-	}
+-
+-	if (c->redirect_urls_allowed != NULL) {
+-		for (hi = apr_hash_first(NULL, c->redirect_urls_allowed); hi; hi =
+-				apr_hash_next(hi)) {
+-			apr_hash_this(hi, (const void**) &c_host, NULL, NULL);
+-			if (oidc_util_regexp_first_match(r->pool, url, c_host,
+-					NULL, err_str) == TRUE)
+-				break;
+-		}
+-		if (hi == NULL) {
+-			*err_str = apr_pstrdup(r->pool, "URL not allowed");
+-			*err_desc =
+-					apr_psprintf(r->pool,
+-							"value does not match the list of allowed redirect URLs: %s",
+-							url);
+-			oidc_error(r, "%s: %s", *err_str, *err_desc);
+-			return FALSE;
+-		}
+-	} else if ((uri.hostname != NULL) && (restrict_to_host == TRUE)) {
+-		c_host = oidc_get_current_url_host(r);
+-		if ((strstr(c_host, uri.hostname) == NULL)
+-				|| (strstr(uri.hostname, c_host) == NULL)) {
+-			*err_str = apr_pstrdup(r->pool, "Invalid Request");
+-			*err_desc =
+-					apr_psprintf(r->pool,
+-							"URL value \"%s\" does not match the hostname of the current request \"%s\"",
+-							apr_uri_unparse(r->pool, &uri, 0), c_host);
+-			oidc_error(r, "%s: %s", *err_str, *err_desc);
+-			return FALSE;
+-		}
+-	}
+-
+-	if ((uri.hostname == NULL) && (strstr(url, "/") != url)) {
+-		*err_str = apr_pstrdup(r->pool, "Malformed URL");
+-		*err_desc =
+-				apr_psprintf(r->pool,
+-						"No hostname was parsed and it does not seem to be relative, i.e starting with '/': %s",
+-						url);
+-		oidc_error(r, "%s: %s", *err_str, *err_desc);
+-		return FALSE;
+-	} else if ((uri.hostname == NULL) && (strstr(url, "//") == url)) {
+-		*err_str = apr_pstrdup(r->pool, "Malformed URL");
+-		*err_desc = apr_psprintf(r->pool,
+-				"No hostname was parsed and starting with '//': %s", url);
+-		oidc_error(r, "%s: %s", *err_str, *err_desc);
+-		return FALSE;
+-	} else if ((uri.hostname == NULL) && (strstr(url, "/\\") == url)) {
+-		*err_str = apr_pstrdup(r->pool, "Malformed URL");
+-		*err_desc = apr_psprintf(r->pool,
+-				"No hostname was parsed and starting with '/\\': %s", url);
+-		oidc_error(r, "%s: %s", *err_str, *err_desc);
+-		return FALSE;
+-	}
+-
+-	/* validate the URL to prevent HTTP header splitting */
+-	if (((strstr(url, "\n") != NULL) || strstr(url, "\r") != NULL)) {
+-		*err_str = apr_pstrdup(r->pool, "Invalid URL");
+-		*err_desc =
+-				apr_psprintf(r->pool,
+-						"URL value \"%s\" contains illegal \"\n\" or \"\r\" character(s)",
+-						url);
+-		oidc_error(r, "%s: %s", *err_str, *err_desc);
+-		return FALSE;
+-	}
+-
+-    return TRUE;
+-}
+-
+ /*
+  * perform (single) logout
+  */
+-- 
+2.31.1
+
diff --git a/SPECS/mod_auth_openidc.spec b/SPECS/mod_auth_openidc.spec
index 6d55854..ae4c145 100644
--- a/SPECS/mod_auth_openidc.spec
+++ b/SPECS/mod_auth_openidc.spec
@@ -15,7 +15,7 @@
 
 Name:		mod_auth_openidc
 Version:	2.3.7
-Release:	8%{?dist}
+Release:	9%{?dist}
 Summary:	OpenID Connect auth module for Apache HTTP Server
 
 Group:		System Environment/Daemons
@@ -42,7 +42,10 @@ Patch16: 0016-always-add-a-SameSite-value-to-the-Set-Cookie-header.patch
 Patch17: 0017-fix-also-add-SameSite-None-to-by-value-session-cooki.patch
 Patch18: 0018-add-note-on-usage-of-OIDC_SET_COOKIE_APPEND-in-the-s.patch
 Patch19: 0019-add-SameSite-attribute-on-cookie-clearance-logout.patch
-
+Patch20: 0020-prevent-open-redirect-on-refresh-token-requests-rele.patch
+Patch21: 0021-prevent-XSS-and-open-redirect-on-OIDC-session-manage.patch
+Patch22: 0022-replace-potentially-harmful-backslashes-with-forward.patch
+Patch23: 0023-apply-OIDCRedirectURLsAllowed-setting-to-target_link.patch
 
 BuildRequires:  gcc
 BuildRequires:	httpd-devel
@@ -82,6 +85,10 @@ an OpenID Connect Relying Party and/or OAuth 2.0 Resource Server.
 %patch17 -p1
 %patch18 -p1
 %patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
 
 %build
 # workaround rpm-buildroot-usage
@@ -134,6 +141,10 @@ install -m 700 -d $RPM_BUILD_ROOT%{httpd_pkg_cache_dir}/cache
 %dir %attr(0700, apache, apache) %{httpd_pkg_cache_dir}/cache
 
 %changelog
+* Fri Oct 29 2021 Tomas Halman <thalman@redhat.com> - 2.3.7-9
+- Resolves: rhbz#2001853 - CVE-2021-39191 open redirect by supplying a crafted URL
+                           in the target_link_uri parameter
+
 * Tue Nov 17 2020 Jakub Hrozek <jhrozek@redhat.com> - 2.3.7-8
 - Resolves: rhbz#1823756 - Backport SameSite=None cookie from
                            mod_auth_openidc upstream to support latest browsers