From 636cd867d1410fe7513e233884b1b00792d74451 Mon Sep 17 00:00:00 2001 From: Ivan Ovchinnikov Date: Tue, 11 Nov 2025 18:59:15 +0000 Subject: [PATCH] Enable TLS certificate verification for OIDC IdP upstream connections. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates `openid_connect.server_conf` to enforce secure TLS settings on all IdP-bound requests (`/_token`, `/_refresh`, `/_jwks_uri`). This adds: - `proxy_ssl_verify on` to enforce verification of the OP’s TLS certificate. - `proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt` to use the system (Debian/Ubuntu/Alpine) CA bundle for trust. - `proxy_ssl_verify_depth 2` to allow certificate chains up to one intermediate CA. --- README.md | 3 +++ openid_connect.server_conf | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d90970a..fd800f9 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,8 @@ Manual configuration involves reviewing the following files so that they match y * No changes are usually required here * Modify the `resolver` directive to match a DNS server that is capable of resolving the IdP defined in `$oidc_token_endpoint` and `$oidc_end_session_endpoint` * If using [`auth_jwt_key_request`](http://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_key_request) to automatically fetch the JWK file from the IdP then modify the validity period and other caching options to suit your IdP + * TLS certificate verification for all IdP-bound requests (token, refresh, JWKS) is enabled by default. NGINX Plus uses the system CA bundle at `/etc/ssl/certs/ca-certificates.crt` (via [`proxy_ssl_trusted_certificate`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_trusted_certificate)) to validate the IdP’s TLS certificate. If the IdP’s certificate is signed by a private or custom CA, append that CA to this bundle or update the `proxy_ssl_trusted_certificate` path accordingly. + * The [`proxy_ssl_verify_depth`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify_depth) directive is set to **2** by default, allowing one intermediate CA in the chain. This is sufficient for most public IdPs. * **openid_connect.js** - this is the JavaScript code for performing the authorization code exchange and nonce hashing * No changes are required unless modifying the code exchange or validation process @@ -320,3 +322,4 @@ This reference implementation for OpenID Connect is supported for NGINX Plus sub * **R28** Access token support. Added support for access token to authorize NGINX to access protected backend. * **R32** Added support for `client_secret_basic` client authentication method. * **R33** Refactor code to use async/await. Implement Front-Channel Logout endpoint. + * **R36** Enable TLS certificate verification for all IdP-bound requests by default. diff --git a/openid_connect.server_conf b/openid_connect.server_conf index 311dcd0..bda5911 100644 --- a/openid_connect.server_conf +++ b/openid_connect.server_conf @@ -13,7 +13,12 @@ proxy_cache jwk; # Cache the JWK Set received from IdP proxy_cache_valid 200 12h; # How long to consider keys "fresh" proxy_cache_use_stale error timeout updating; # Use old JWK Set if cannot reach IdP - proxy_ssl_server_name on; # For SNI to the IdP + + proxy_ssl_verify on; # Enforce TLS certificate verification + proxy_ssl_verify_depth 2; # Allow intermediate CA chains of depth 2 + proxy_ssl_server_name on; # Send SNI to IdP host + proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; # Use system CA bundle + proxy_method GET; # In case client request was non-GET proxy_set_header Content-Length ""; # '' proxy_pass $oidc_jwt_keyfile; # Expecting to find a URI here @@ -43,7 +48,11 @@ # Exclude client headers to avoid CORS errors with certain IdPs (e.g., Microsoft Entra ID) proxy_pass_request_headers off; - proxy_ssl_server_name on; # For SNI to the IdP + proxy_ssl_verify on; # Enforce TLS certificate verification + proxy_ssl_verify_depth 2; # Allow intermediate CA chains of depth 2 + proxy_ssl_server_name on; # Send SNI to IdP host + proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; # Use system CA bundle + proxy_set_header Content-Type "application/x-www-form-urlencoded"; proxy_set_header Authorization $arg_secret_basic; proxy_pass $oidc_token_endpoint; @@ -58,7 +67,11 @@ # Exclude client headers to avoid CORS errors with certain IdPs (e.g., Microsoft Entra ID) proxy_pass_request_headers off; - proxy_ssl_server_name on; # For SNI to the IdP + proxy_ssl_verify on; # Enforce TLS certificate verification + proxy_ssl_verify_depth 2; # Allow intermediate CA chains of depth 2 + proxy_ssl_server_name on; # Send SNI to IdP host + proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; # Use system CA bundle + proxy_set_header Content-Type "application/x-www-form-urlencoded"; proxy_set_header Authorization $arg_secret_basic; proxy_pass $oidc_token_endpoint;