Blame SOURCES/0004-Backport-of-improve-validation-of-the-post-logout-UR.patch

8911f3
From 0486590c2944b39b480ab1713026ea402420863e Mon Sep 17 00:00:00 2001
8911f3
From: Jakub Hrozek <jhrozek@redhat.com>
8911f3
Date: Mon, 16 Mar 2020 21:09:37 +0100
8911f3
Subject: [PATCH 4/6] Backport of improve validation of the post-logout URL;
8911f3
 closes #449
8911f3
8911f3
---
8911f3
 src/mod_auth_openidc.c | 90 +++++++++++++++++++++++++-----------------
8911f3
 1 file changed, 53 insertions(+), 37 deletions(-)
8911f3
8911f3
diff --git a/src/mod_auth_openidc.c b/src/mod_auth_openidc.c
8911f3
index b504ecbf62f839a82ad205fa5f825f9a8428dfdb..431e89e086fbb72f56ea2a212e63c6ac693f62a2 100644
8911f3
--- a/src/mod_auth_openidc.c
8911f3
+++ b/src/mod_auth_openidc.c
8911f3
@@ -2083,6 +2083,52 @@ static int oidc_handle_logout_request(request_rec *r, oidc_cfg *c,
8911f3
 	return HTTP_MOVED_TEMPORARILY;
8911f3
 }
8911f3
 
8911f3
+static apr_byte_t oidc_validate_post_logout_url(request_rec *r, const char *url, char **err_str, char **err_desc) {
8911f3
+       apr_uri_t uri;
8911f3
+       const char *c_host = NULL;
8911f3
+
8911f3
+       if (apr_uri_parse(r->pool, url, &uri) != APR_SUCCESS) {
8911f3
+               *err_str = apr_pstrdup(r->pool, "Malformed URL");
8911f3
+               *err_desc = apr_psprintf(r->pool, "Logout URL malformed: %s", url);
8911f3
+               oidc_error(r, "%s: %s", *err_str, *err_desc);
8911f3
+               return FALSE;
8911f3
+       }
8911f3
+
8911f3
+       c_host = oidc_get_current_url_host(r);
8911f3
+       if ((uri.hostname != NULL)
8911f3
+                       && ((strstr(c_host, uri.hostname) == NULL)
8911f3
+                                       || (strstr(uri.hostname, c_host) == NULL))) {
8911f3
+               *err_str = apr_pstrdup(r->pool, "Invalid Request");
8911f3
+               *err_desc =
8911f3
+                               apr_psprintf(r->pool,
8911f3
+                                               "logout value \"%s\" does not match the hostname of the current request \"%s\"",
8911f3
+                                               apr_uri_unparse(r->pool, &uri, 0), c_host);
8911f3
+               oidc_error(r, "%s: %s", *err_str, *err_desc);
8911f3
+               return FALSE;
8911f3
+       } else if (strstr(url, "/") != url) {
8911f3
+               *err_str = apr_pstrdup(r->pool, "Malformed URL");
8911f3
+               *err_desc =
8911f3
+                               apr_psprintf(r->pool,
8911f3
+                                               "No hostname was parsed and it does not seem to be relative, i.e starting with '/': %s",
8911f3
+                                               url);
8911f3
+               oidc_error(r, "%s: %s", *err_str, *err_desc);
8911f3
+               return FALSE;
8911f3
+       }
8911f3
+
8911f3
+       /* validate the URL to prevent HTTP header splitting */
8911f3
+       if (((strstr(url, "\n") != NULL) || strstr(url, "\r") != NULL)) {
8911f3
+               *err_str = apr_pstrdup(r->pool, "Invalid Request");
8911f3
+               *err_desc =
8911f3
+                               apr_psprintf(r->pool,
8911f3
+                                               "logout value \"%s\" contains illegal \"\n\" or \"\r\" character(s)",
8911f3
+                                               url);
8911f3
+               oidc_error(r, "%s: %s", *err_str, *err_desc);
8911f3
+               return FALSE;
8911f3
+       }
8911f3
+
8911f3
+       return TRUE;
8911f3
+}
8911f3
+
8911f3
 /*
8911f3
  * perform (single) logout
8911f3
  */
8911f3
@@ -2090,6 +2136,8 @@ static int oidc_handle_logout(request_rec *r, oidc_cfg *c, session_rec *session)
8911f3
 
8911f3
 	/* pickup the command or URL where the user wants to go after logout */
8911f3
 	char *url = NULL;
8911f3
+	char *error_str = NULL;
8911f3
+	char *error_description = NULL;
8911f3
 	oidc_util_get_request_parameter(r, "logout", &url;;
8911f3
 
8911f3
 	oidc_debug(r, "enter (url=%s)", url);
8911f3
@@ -2103,44 +2151,12 @@ static int oidc_handle_logout(request_rec *r, oidc_cfg *c, session_rec *session)
8911f3
 		url = c->default_slo_url;
8911f3
 
8911f3
 	} else {
8911f3
-
8911f3
 		/* do input validation on the logout parameter value */
8911f3
-
8911f3
-		const char *error_description = NULL;
8911f3
-		apr_uri_t uri;
8911f3
-
8911f3
-		if (apr_uri_parse(r->pool, url, &uri) != APR_SUCCESS) {
8911f3
-			const char *error_description = apr_psprintf(r->pool,
8911f3
-					"Logout URL malformed: %s", url);
8911f3
-			oidc_error(r, "%s", error_description);
8911f3
-			return oidc_util_html_send_error(r, c->error_template,
8911f3
-					"Malformed URL", error_description,
8911f3
-					HTTP_INTERNAL_SERVER_ERROR);
8911f3
-
8911f3
-		}
8911f3
-
8911f3
-		if ((strstr(r->hostname, uri.hostname) == NULL)
8911f3
-				|| (strstr(uri.hostname, r->hostname) == NULL)) {
8911f3
-			error_description =
8911f3
-					apr_psprintf(r->pool,
8911f3
-							"logout value \"%s\" does not match the hostname of the current request \"%s\"",
8911f3
-							apr_uri_unparse(r->pool, &uri, 0), r->hostname);
8911f3
-			oidc_error(r, "%s", error_description);
8911f3
-			return oidc_util_html_send_error(r, c->error_template,
8911f3
-					"Invalid Request", error_description,
8911f3
-					HTTP_INTERNAL_SERVER_ERROR);
8911f3
-		}
8911f3
-
8911f3
-		/* validate the URL to prevent HTTP header splitting */
8911f3
-		if (((strstr(url, "\n") != NULL) || strstr(url, "\r") != NULL)) {
8911f3
-			error_description =
8911f3
-					apr_psprintf(r->pool,
8911f3
-							"logout value \"%s\" contains illegal \"\n\" or \"\r\" character(s)",
8911f3
-							url);
8911f3
-			oidc_error(r, "%s", error_description);
8911f3
-			return oidc_util_html_send_error(r, c->error_template,
8911f3
-					"Invalid Request", error_description,
8911f3
-					HTTP_INTERNAL_SERVER_ERROR);
8911f3
+		if (oidc_validate_post_logout_url(r, url, &error_str,
8911f3
+			&error_description) == FALSE) {
8911f3
+		return oidc_util_html_send_error(r, c->error_template, error_str,
8911f3
+			error_description,
8911f3
+			HTTP_BAD_REQUEST); 
8911f3
 		}
8911f3
 	}
8911f3
 
8911f3
-- 
8911f3
2.21.1
8911f3