Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package apache2-mod_auth_openidc for openSUSE:Factory checked in at 2021-09-06 15:58:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/apache2-mod_auth_openidc (Old) and /work/SRC/openSUSE:Factory/.apache2-mod_auth_openidc.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "apache2-mod_auth_openidc" Mon Sep 6 15:58:07 2021 rev:23 rq:917070 version:2.4.9.4 Changes: -------- --- /work/SRC/openSUSE:Factory/apache2-mod_auth_openidc/apache2-mod_auth_openidc.changes 2021-08-30 13:55:39.101856550 +0200 +++ /work/SRC/openSUSE:Factory/.apache2-mod_auth_openidc.new.1899/apache2-mod_auth_openidc.changes 2021-09-06 15:58:23.277290249 +0200 @@ -1,0 +2,11 @@ +Fri Sep 3 17:47:35 UTC 2021 - Michael Str??der <mich...@stroeder.com> + +- update to 2.4.9.4 + * Security + - prevent open redirect by applying OIDCRedirectURLsAllowed setting to + target_link_uri; closes #672 + * Bugfixes + - don't apply authz in discovery process; fixes step up authentication + when combined with Discovery + +------------------------------------------------------------------- Old: ---- mod_auth_openidc-2.4.9.3.tar.gz New: ---- mod_auth_openidc-2.4.9.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apache2-mod_auth_openidc.spec ++++++ --- /var/tmp/diff_new_pack.MRp0yL/_old 2021-09-06 15:58:23.833290121 +0200 +++ /var/tmp/diff_new_pack.MRp0yL/_new 2021-09-06 15:58:23.833290121 +0200 @@ -17,7 +17,7 @@ Name: apache2-mod_auth_openidc -Version: 2.4.9.3 +Version: 2.4.9.4 Release: 0 Summary: Apache2.x module for an OpenID Connect enabled Identity Provider License: Apache-2.0 ++++++ mod_auth_openidc-2.4.9.3.tar.gz -> mod_auth_openidc-2.4.9.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.9.3/AUTHORS new/mod_auth_openidc-2.4.9.4/AUTHORS --- old/mod_auth_openidc-2.4.9.3/AUTHORS 2021-08-23 15:53:13.000000000 +0200 +++ new/mod_auth_openidc-2.4.9.4/AUTHORS 2021-09-03 10:12:37.000000000 +0200 @@ -73,5 +73,7 @@ Steffen Greber <https://github.com/codemaker219> Iain Heggie <https://github.com/iainh> Dirk Kok <https://github.com/Foxite> + Meheni https://github.com/Meheni + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.9.3/ChangeLog new/mod_auth_openidc-2.4.9.4/ChangeLog --- old/mod_auth_openidc-2.4.9.3/ChangeLog 2021-08-26 18:44:21.000000000 +0200 +++ new/mod_auth_openidc-2.4.9.4/ChangeLog 2021-09-03 10:12:15.000000000 +0200 @@ -1,5 +1,11 @@ +09/03/2021 +- don't apply authz in discovery process; fixes 2.4.9.3 +- apply OIDCRedirectURLsAllowed setting to target_link_uri; closes #672; thanks @Meheni +- release 2.4.9.4 + 08/26/2021 - don't apply authz to the redirect URI; fixes ac5686495a51bc93e257e42bfdc9c9c46252feb1 +- bump to 2.4.9.3 08/20/2021 - fix graceful restart (regression); see #458; thanks @Foxite @@ -25,7 +31,6 @@ - don't clear POST params authn on token revocation; thanks @iainh - bump to 2.4.9rc0 -closes #626 07/02/2021 - handle discovery in the content handler - return OK in the content handler for calls to the redirect URI and when preserving POST data diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.9.3/auth_openidc.conf new/mod_auth_openidc-2.4.9.4/auth_openidc.conf --- old/mod_auth_openidc-2.4.9.3/auth_openidc.conf 2021-08-23 15:53:13.000000000 +0200 +++ new/mod_auth_openidc-2.4.9.4/auth_openidc.conf 2021-09-03 10:32:42.000000000 +0200 @@ -918,8 +918,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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.9.3/configure new/mod_auth_openidc-2.4.9.4/configure --- old/mod_auth_openidc-2.4.9.3/configure 2021-08-26 18:48:28.000000000 +0200 +++ new/mod_auth_openidc-2.4.9.4/configure 2021-09-03 10:13:00.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for mod_auth_openidc 2.4.9.3. +# Generated by GNU Autoconf 2.71 for mod_auth_openidc 2.4.9.4. # # Report bugs to <hans.zandb...@zmartzone.eu>. # @@ -610,8 +610,8 @@ # Identity of this package. PACKAGE_NAME='mod_auth_openidc' PACKAGE_TARNAME='mod_auth_openidc' -PACKAGE_VERSION='2.4.9.3' -PACKAGE_STRING='mod_auth_openidc 2.4.9.3' +PACKAGE_VERSION='2.4.9.4' +PACKAGE_STRING='mod_auth_openidc 2.4.9.4' PACKAGE_BUGREPORT='hans.zandb...@zmartzone.eu' PACKAGE_URL='' @@ -1301,7 +1301,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures mod_auth_openidc 2.4.9.3 to adapt to many kinds of systems. +\`configure' configures mod_auth_openidc 2.4.9.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1364,7 +1364,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of mod_auth_openidc 2.4.9.3:";; + short | recursive ) echo "Configuration of mod_auth_openidc 2.4.9.4:";; esac cat <<\_ACEOF @@ -1478,7 +1478,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -mod_auth_openidc configure 2.4.9.3 +mod_auth_openidc configure 2.4.9.4 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1634,7 +1634,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by mod_auth_openidc $as_me 2.4.9.3, which was +It was created by mod_auth_openidc $as_me 2.4.9.4, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -2292,7 +2292,7 @@ -NAMEVER=mod_auth_openidc-2.4.9.3 +NAMEVER=mod_auth_openidc-2.4.9.4 # This section defines the --with-apxs2 option. @@ -4952,7 +4952,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by mod_auth_openidc $as_me 2.4.9.3, which was +This file was extended by mod_auth_openidc $as_me 2.4.9.4, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5007,7 +5007,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -mod_auth_openidc config.status 2.4.9.3 +mod_auth_openidc config.status 2.4.9.4 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.9.3/configure.ac new/mod_auth_openidc-2.4.9.4/configure.ac --- old/mod_auth_openidc-2.4.9.3/configure.ac 2021-08-26 18:46:49.000000000 +0200 +++ new/mod_auth_openidc-2.4.9.4/configure.ac 2021-09-03 10:11:03.000000000 +0200 @@ -1,4 +1,4 @@ -AC_INIT([mod_auth_openidc],[2.4.9.3],[hans.zandb...@zmartzone.eu]) +AC_INIT([mod_auth_openidc],[2.4.9.4],[hans.zandb...@zmartzone.eu]) AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.9.3/src/mod_auth_openidc.c new/mod_auth_openidc-2.4.9.4/src/mod_auth_openidc.c --- old/mod_auth_openidc-2.4.9.3/src/mod_auth_openidc.c 2021-08-26 18:39:11.000000000 +0200 +++ new/mod_auth_openidc-2.4.9.4/src/mod_auth_openidc.c 2021-09-03 10:37:41.000000000 +0200 @@ -2457,6 +2457,96 @@ 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 */ @@ -2467,6 +2557,8 @@ *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); @@ -2510,7 +2602,7 @@ 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, @@ -2519,6 +2611,14 @@ 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) @@ -2947,95 +3047,6 @@ return rc; } -#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; -} /* * perform (single) logout @@ -4002,6 +4013,9 @@ oidc_authenticate_user(r, c, NULL, oidc_get_current_url(r), NULL, NULL, NULL, oidc_dir_cfg_path_auth_request_params(r), oidc_dir_cfg_path_scope(r)); + if (oidc_request_state_get(r, OIDC_REQUEST_STATE_KEY_DISCOVERY) != NULL) + return AUTHZ_GRANTED; + const char *location = oidc_util_hdr_out_location_get(r); if (location != NULL) { oidc_debug(r, "send HTML refresh with authorization redirect: %s", location); @@ -4030,15 +4044,12 @@ oidc_debug(r, "enter: require_args=\"%s\"", require_args); - oidc_cfg *c = ap_get_module_config(r->server->module_config, - &auth_openidc_module); - /* check for anonymous access and PASS mode */ if (r->user != NULL && strlen(r->user) == 0) { r->user = NULL; if (oidc_dir_cfg_unauth_action(r) == OIDC_UNAUTH_PASS) return AUTHZ_GRANTED; - if (oidc_util_request_matches_url(r, oidc_get_redirect_uri(r, c)) == TRUE) + if (oidc_request_state_get(r, OIDC_REQUEST_STATE_KEY_DISCOVERY) != NULL) return AUTHZ_GRANTED; } @@ -4127,7 +4138,7 @@ r->user = NULL; if (oidc_dir_cfg_unauth_action(r) == OIDC_UNAUTH_PASS) return OK; - if (oidc_util_request_matches_url(r, oidc_get_redirect_uri(r, c)) == TRUE) + if if (oidc_request_state_get(r, OIDC_REQUEST_STATE_KEY_DISCOVERY) != NULL) return OK; }