Package: release.debian.org Severity: normal Tags: bullseye User: release.debian....@packages.debian.org Usertags: pu X-Debbugs-Cc: t...@security.debian.org
Dear stable release managers and security team, I kindly ask you to allow version 2.4.9.4 of the aforementioned package to be included in proposed-updates to fix CVE-2021-39191 and the regression mentioned in #891224#49ff. I would prefer to just be able to introduce this plainly as the (smaller-than-patch) upstream release for simplicity. [ Reason ] To quote the corresponding changelog entry: libapache2-mod-auth-openidc (2.4.9.4-1) unstable; urgency=medium * New upstream version 2.4.9.4 * Fix "CVE-2021-39191" (Closes: #993648) * 2.4.9.2 fixed a regression regarding segfault at reload/restart (Closes: #883616, #891224, #868949) -- Moritz Schlarb <schla...@uni-mainz.de> Tue, 07 Sep 2021 09:37:15 +0200 [ Impact ] Apache2 continues to segfault when graceful reloading. CVE-2021-39191 continues to be exploitable ("There are no known workarounds aside from upgrading to a patched version.") [ Tests ] We've used that version on some of our internal testing servers for the two months it was current without any further issues. [ Risks ] The total change in actual source code is not that big and most of it actually comes from the fix for CVE-2021-39191. https://github.com/zmartzone/mod_auth_openidc/compare/v2.4.9...v2.4.9.4 [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable Thanks, Moritz
diff -Nru libapache2-mod-auth-openidc-2.4.9/auth_openidc.conf libapache2-mod-auth-openidc-2.4.9.4/auth_openidc.conf --- libapache2-mod-auth-openidc-2.4.9/auth_openidc.conf 2021-07-22 18:31:06.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/auth_openidc.conf 2021-09-03 10:41:21.000000000 +0200 @@ -744,6 +744,8 @@ # "claims" : the claims in the id_token are passed in individual headers/environment variables # "payload" : the payload of the id_token is passed as a JSON object in the "OIDC_id_token_payload" header/environment variable # "serialized" : the complete id_token is passed in compact serialized format in the "OIDC_id_token" header/environment variable +# Note that when OIDCSessionType client-cookie is set, the id_token itself is not stored in the session/cookie and as such +# the headers for the "payload" and "serialized" option will not be created. # When not defined the default "claims" is used. #OIDCPassIDTokenAs [claims|payload|serialized]+ @@ -886,6 +888,8 @@ # timeout (int) : the session inactivity timeout (Unix timestamp in seconds) # remote_user (string) : the remote user name # session (object) : (for debugging) mod_auth_openidc specific session data such as "remote user", "session expiry", "session id" and a "state" object +# Note that when using ProxyPass / you may have to add a proxy exception for the Redirect URI +# for this to work, e.g. ProxyPass /redirect_uri ! # When not defined the session hook will not return any data but a HTTP 404 #OIDCInfoHook [iat|access_token|access_token_expires|id_token|userinfo|refresh_token|exp|timeout|remote_user|session]+ @@ -914,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 -Nru libapache2-mod-auth-openidc-2.4.9/AUTHORS libapache2-mod-auth-openidc-2.4.9.4/AUTHORS --- libapache2-mod-auth-openidc-2.4.9/AUTHORS 2021-07-22 18:31:06.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/AUTHORS 2021-09-03 10:41:21.000000000 +0200 @@ -72,5 +72,8 @@ 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 -Nru libapache2-mod-auth-openidc-2.4.9/ChangeLog libapache2-mod-auth-openidc-2.4.9.4/ChangeLog --- libapache2-mod-auth-openidc-2.4.9/ChangeLog 2021-07-22 18:31:06.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/ChangeLog 2021-09-03 10:41:21.000000000 +0200 @@ -1,7 +1,29 @@ +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 +- bump to 2.4.9.2 + +08/18/2021 +- preserve session cookie in the event of a cache backend failure +- update the id_token in the session cache if one is provided while refreshing the access token + +08/13/2021 +- fix retried Redis commands after a reconnect; thanks @iainh +- release 2.4.9.1 + 07/22/2021 - use redisvCommand to avoid crash with crafted key when using Redis without encryption; thanks @thomas-chauchefoin-sonarsource - replace potentially harmful backslashes with forward slashes when validating redirection URLs; thanks @thomas-chauchefoin-sonarsource - release 2.4.9 +- don't use DEFAULT_LIMIT_REQUEST_LINE constant; since it does not exist in Apache 2.2.x 07/15/2021 - verify that "alg" is not none in logout_token explicitly @@ -9,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 -Nru libapache2-mod-auth-openidc-2.4.9/configure.ac libapache2-mod-auth-openidc-2.4.9.4/configure.ac --- libapache2-mod-auth-openidc-2.4.9/configure.ac 2021-07-22 18:31:06.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/configure.ac 2021-09-03 10:41:21.000000000 +0200 @@ -1,4 +1,4 @@ -AC_INIT([mod_auth_openidc],[2.4.9],[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 -Nru libapache2-mod-auth-openidc-2.4.9/.cproject libapache2-mod-auth-openidc-2.4.9.4/.cproject --- libapache2-mod-auth-openidc-2.4.9/.cproject 2021-07-22 18:31:06.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/.cproject 2021-09-03 10:41:21.000000000 +0200 @@ -18,7 +18,7 @@ </extensions> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools,org.eclipse.cdt.build.core.buildType=org.eclipse.linuxtools.cdt.autotools.core.buildType.default" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.1562680719" name="Build (GNU)" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.connection=unix:///var/run/docker.sock,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="org.eclipse.linuxtools.cdt.autotools.core.configuration.build"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools,org.eclipse.cdt.build.core.buildType=org.eclipse.linuxtools.cdt.autotools.core.buildType.default" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.1562680719" name="Build (GNU)" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.connection=unix:///var/run/docker.sock" parent="org.eclipse.linuxtools.cdt.autotools.core.configuration.build"> <folderInfo id="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.1562680719." name="/" resourcePath=""> <toolChain id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.617277945" name="GNU Autotools Toolchain" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolChain"> <targetPlatform id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform.359991688" isAbstract="false" name="GNU Autotools Target Platform" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform"/> @@ -38,6 +38,8 @@ <listOptionValue builtIn="false" value="/Users/hzandbelt/projects/nginx-1.15.5/src/http"/> <listOptionValue builtIn="false" value="/usr/local/include"/> <listOptionValue builtIn="false" value="/opt/local/include"/> + <listOptionValue builtIn="false" value="/opt/local/include/apache2"/> + <listOptionValue builtIn="false" value="/opt/local/include/apr-1"/> </option> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.2047978831" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols"> <listOptionValue builtIn="false" value="HAVE_LIBHIREDIS=1"/> @@ -81,7 +83,7 @@ </extensions> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools,org.eclipse.cdt.build.core.buildType=org.eclipse.linuxtools.cdt.autotools.core.buildType.debug" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug.1551656597" name="Debug (GNU)" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.connection=unix:///var/run/docker.sock,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools,org.eclipse.cdt.build.core.buildType=org.eclipse.linuxtools.cdt.autotools.core.buildType.debug" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug.1551656597" name="Debug (GNU)" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.connection=unix:///var/run/docker.sock" parent="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug"> <folderInfo id="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug.1551656597." name="/" resourcePath=""> <toolChain id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.debug.1772566252" name="GNU Autotools Toolchain" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolChain.debug"> <targetPlatform id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform.debug.1422301246" isAbstract="false" name="GNU Autotools Target Platform" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform.debug"/> @@ -95,6 +97,7 @@ <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.300127578" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> <listOptionValue builtIn="false" value="/Users/hzandbelt/projects/nginx-1.15.5/src/core"/> <listOptionValue builtIn="false" value="/Users/hzandbelt/projects/nginx-1.15.5/src/http"/> + <listOptionValue builtIn="false" value="/opt/local/include/apache2"/> </option> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.854310462" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols"> <listOptionValue builtIn="false" value="HAVE_LIBHIREDIS=1"/> @@ -115,6 +118,7 @@ </sourceEntries> </configuration> </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> </cconfiguration> </storageModule> <storageModule moduleId="org.eclipse.cdt.core.pathentry"> @@ -177,4 +181,12 @@ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> </scannerConfigBuildInfo> </storageModule> + <storageModule moduleId="refreshScope" versionNumber="2"> + <configuration configurationName="Debug (GNU)"> + <resource resourceType="PROJECT" workspacePath="/mod_auth_openidc"/> + </configuration> + <configuration configurationName="Build (GNU)"> + <resource resourceType="PROJECT" workspacePath="/mod_auth_openidc"/> + </configuration> + </storageModule> </cproject> \ No newline at end of file diff -Nru libapache2-mod-auth-openidc-2.4.9/debian/changelog libapache2-mod-auth-openidc-2.4.9.4/debian/changelog --- libapache2-mod-auth-openidc-2.4.9/debian/changelog 2021-08-02 11:45:39.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/debian/changelog 2022-02-23 12:16:08.000000000 +0100 @@ -1,3 +1,12 @@ +libapache2-mod-auth-openidc (2.4.9.4-1+deb11u1) bullseye; urgency=medium + + * New upstream version 2.4.9.4 + * Fix "CVE-2021-39191" (Closes: #993648) + * 2.4.9.2 fixed a regression regarding segfault at reload/restart + (Closes: #883616, #891224, #868949) + + -- Moritz Schlarb <schla...@uni-mainz.de> Wed, 23 Feb 2022 12:16:08 +0100 + libapache2-mod-auth-openidc (2.4.9-1) unstable; urgency=medium * New upstream version 2.4.9 diff -Nru libapache2-mod-auth-openidc-2.4.9/debian/gbp.conf libapache2-mod-auth-openidc-2.4.9.4/debian/gbp.conf --- libapache2-mod-auth-openidc-2.4.9/debian/gbp.conf 2021-08-02 11:45:39.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/debian/gbp.conf 2022-02-23 12:16:06.000000000 +0100 @@ -1,2 +1,3 @@ [DEFAULT] +debian-branch=bullseye pristine-tar = True diff -Nru libapache2-mod-auth-openidc-2.4.9/.github/workflows/codeql-analysis.yml libapache2-mod-auth-openidc-2.4.9.4/.github/workflows/codeql-analysis.yml --- libapache2-mod-auth-openidc-2.4.9/.github/workflows/codeql-analysis.yml 1970-01-01 01:00:00.000000000 +0100 +++ libapache2-mod-auth-openidc-2.4.9.4/.github/workflows/codeql-analysis.yml 2021-09-03 10:41:21.000000000 +0200 @@ -0,0 +1,78 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + schedule: + - cron: '19 13 * * 6' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install packages + run: | + sudo apt-get update + sudo apt-get install -y apache2-dev libcjose-dev libssl-dev + sudo apt-get install -y libjansson-dev libcurl4-openssl-dev libhiredis-dev + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + #- name: Autobuild + # uses: github/codeql-action/autobuild@v1 + + # âšī¸ Command-line programs to run using the OS shell. + # đ https://git.io/JvXDl + + # âī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + - run: | + ./autogen.sh + ./configure + make test + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff -Nru libapache2-mod-auth-openidc-2.4.9/src/cache/common.c libapache2-mod-auth-openidc-2.4.9.4/src/cache/common.c --- libapache2-mod-auth-openidc-2.4.9/src/cache/common.c 2021-07-22 18:31:06.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/src/cache/common.c 2021-09-03 10:41:21.000000000 +0200 @@ -220,7 +220,7 @@ // oidc_sdebug(s, "processing: %d (m=%pp,s=%pp, p=%d)", (m && m->sema) ? *m->sema : -1, m->mutex ? m->mutex : 0, s, m->is_parent); - if ((m->shm != NULL) && (*m->sema == 0)) { + if ((m->shm != NULL) && (*m->sema == 0) && (m->is_parent == TRUE)) { rv = apr_shm_destroy(m->shm); oidc_sdebug(s, "apr_shm_destroy for semaphore returned: %d", rv); diff -Nru libapache2-mod-auth-openidc-2.4.9/src/cache/redis.c libapache2-mod-auth-openidc-2.4.9.4/src/cache/redis.c --- libapache2-mod-auth-openidc-2.4.9/src/cache/redis.c 2021-07-22 18:31:06.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/src/cache/redis.c 2021-09-03 10:41:21.000000000 +0200 @@ -270,7 +270,6 @@ redisReply *reply = NULL; int i = 0; va_list ap; - va_start(ap, format); /* try to execute a command at max 2 times while reconnecting */ for (i = 0; i < OIDC_REDIS_MAX_TRIES; i++) { @@ -279,8 +278,10 @@ if (oidc_cache_redis_connect(r, context) != APR_SUCCESS) break; + va_start(ap, format); /* execute the actual command */ reply = redisvCommand(context->ctx, format, ap); + va_end(ap); /* check for errors, need to return error replies for cache miss case REDIS_REPLY_NIL */ if ((reply != NULL) && (reply->type != REDIS_REPLY_ERROR)) @@ -300,8 +301,6 @@ oidc_cache_redis_free(context); } - va_end(ap); - return reply; } diff -Nru libapache2-mod-auth-openidc-2.4.9/src/mod_auth_openidc.c libapache2-mod-auth-openidc-2.4.9.4/src/mod_auth_openidc.c --- libapache2-mod-auth-openidc-2.4.9/src/mod_auth_openidc.c 2021-07-22 18:31:06.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/src/mod_auth_openidc.c 2021-09-03 10:41:21.000000000 +0200 @@ -1093,6 +1093,33 @@ if (s_refresh_token != NULL) oidc_session_set_refresh_token(r, session, s_refresh_token); + /* if we have a new id_token, store it in the session and update the session max lifetime if required */ + if (s_id_token != NULL) { + /* only store the serialized representation when client cookie based session tracking is not in use */ + if (c->session_type != OIDC_SESSION_TYPE_CLIENT_COOKIE) + oidc_session_set_idtoken(r, session, s_id_token); + + oidc_jwt_t *id_token_jwt = NULL; + oidc_jose_error_t err; + if (oidc_jwt_parse(r->pool, s_id_token, &id_token_jwt, NULL, &err) == TRUE) { + + /* store the claims payload in the id_token for later reference */ + oidc_session_set_idtoken_claims(r, session, + id_token_jwt->payload.value.str); + + if (provider->session_max_duration == 0) { + /* update the session expiry to match the expiry of the id_token */ + apr_time_t session_expires = apr_time_from_sec(id_token_jwt->payload.exp); + oidc_session_set_session_expires(r, session, session_expires); + + /* log message about the updated max session duration */ + oidc_log_session_expires(r, "session max lifetime", session_expires); + } + } else { + oidc_warn(r, "parsing of id_token failed"); + } + } + return TRUE; } @@ -2430,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 */ @@ -2440,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); @@ -2483,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, @@ -2492,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) @@ -2920,95 +3047,6 @@ return rc; } -#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 @@ -3975,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); @@ -4008,6 +4049,8 @@ r->user = NULL; if (oidc_dir_cfg_unauth_action(r) == OIDC_UNAUTH_PASS) return AUTHZ_GRANTED; + if (oidc_request_state_get(r, OIDC_REQUEST_STATE_KEY_DISCOVERY) != NULL) + return AUTHZ_GRANTED; } /* get the set of claims from the request state (they've been set in the authentication part earlier */ @@ -4087,11 +4130,16 @@ */ int oidc_auth_checker(request_rec *r) { + 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 OK; + if if (oidc_request_state_get(r, OIDC_REQUEST_STATE_KEY_DISCOVERY) != NULL) + return OK; } /* get the set of claims from the request state (they've been set in the authentication part earlier */ diff -Nru libapache2-mod-auth-openidc-2.4.9/src/session.c libapache2-mod-auth-openidc-2.4.9.4/src/session.c --- libapache2-mod-auth-openidc-2.4.9/src/session.c 2021-07-22 18:31:06.000000000 +0200 +++ libapache2-mod-auth-openidc-2.4.9.4/src/session.c 2021-09-03 10:41:21.000000000 +0200 @@ -169,7 +169,14 @@ rc = oidc_session_load_cache_by_uuid(r, c, uuid, z); - if (rc == FALSE || z->state == NULL) { + /* cache backend experienced an error while attempting lookup */ + if (rc == FALSE) { + oidc_error(r, "cache backend failure for key %s", uuid); + return FALSE; + } + + /* cache backend does not contain an entry for the given key */ + if (z->state == NULL) { /* delete the session cookie */ oidc_util_set_cookie(r, oidc_cfg_dir_cookie(r), "", 0, OIDC_COOKIE_EXT_SAME_SITE_NONE(r));