Skip to content

Ssl Bundle InsecureTrustManagerFactory Configuration #38920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
syedyusufh opened this issue Dec 24, 2023 · 12 comments
Closed

Ssl Bundle InsecureTrustManagerFactory Configuration #38920

syedyusufh opened this issue Dec 24, 2023 · 12 comments
Labels
status: duplicate A duplicate of another issue

Comments

@syedyusufh
Copy link

How do we configure the Ssl Bundle to use InsecureTrustManagerFactory or custom TrustManagerFactory or skip hostname verification? Couldn't find these details in the documentation. Thanks

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 24, 2023
@Nikunj2788
Copy link

If you need to work with self-signed certificates or for testing purposes, consider using an InsecureTrustManagerFactory. This involves creating a custom SSLContext with an InsecureTrustManager and setting it as the default for your HTTPS connections.

For the Custom manager Factory you have the scenarios where you have specific truststore requirements, create a custom SSLContext with a TrustManagerFactory initialized with your custom truststore. Ensure that you load your truststore appropriately and initialize the SSLContext with the custom trust manager.

@syedyusufh
Copy link
Author

@Nikunj2788 ask is how to do the same via Ssl Bundles. Thanks

@wilkinsona
Copy link
Member

@syedyusufh if you're interacting with a server that uses a self-signed certificate, have you considered trusting that certificate alone on the client-side? That, I think, would be the SSL bundle way of doing things. If you want the client to trust all self-signed certificates or to skip hostname verification, that should be done with client-specific configuration and not through SSL bundles.

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Jan 2, 2024
@syedyusufh
Copy link
Author

@wilkinsona thanks for your comments.

My understanding is that Ssl Bundle manages the trustStore, trustStrategy, etc as part of the Ssl Bundle configuration via application.properties. How do we alter the trust strategy of the Ssl Bundle managed TrustStore still benefiting from the Ssl Bundle benefits?

In other words, how can I construct a full beneficial Ssl Bundle of my underlying JKS with trustStore, trustStrategy programmatically?

Thanks

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 2, 2024
@wilkinsona
Copy link
Member

I don't think I understand why you need both. You can configure an SSL bundle that trusts the server's unsigned certificates or you can configure whatever HTTP client you're using to use an insecure trust manager. Doing one of these negates the need for the other, does it not?

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Jan 2, 2024
@syedyusufh
Copy link
Author

Let us please consider the below sample from Spring.io Blog on how to setup SSL for WebClient via Ssl Bundle,

@Service
public class MyService {

    private final WebClient webClient;

    public MyService(WebClient.Builder webClientBuilder, WebClientSsl ssl) {
        this.webClient = webClientBuilder.baseUrl("https://example.org").apply(ssl.fromBundle("mybundle")).build();
    }
}

How do we now configure the underlying (WebClientSsl) TrustStore to ignore hostNameVerification? We were able to do the same without Ssl Bundle by configuring SslContext, TrustManagerFactory, KeyManagerFactory like below.

// Create an SSL context that uses that certificate
   return SslContextBuilder.forClient()
                         .keyManager(keyManagerFactory)
                         .build();

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 2, 2024
@scottfrederick
Copy link
Contributor

I agree with Andy's statement above:

If you want the client to trust all self-signed certificates or to skip hostname verification, that should be done with client-specific configuration and not through SSL bundles.

Disabling hostname verification is a very dangerous thing to do. It might be useful for testing sometimes, but I don't think Spring Boot should do anything more to make this easy to do so that user's don't mistakenly disable verification in production applications.

We were able to do the same without Ssl Bundle by configuring SslContext, TrustManagerFactory, KeyManagerFactory like below.

One option would be to keep your code that sets up the SSLContext manually, but retrieve the trust material from a configured SSL bundle. To do this, you'd need to auto-wire an instance of SslBundles into your code, retrieve the bundle you want using SslBundles.getBundle(String name). Once you get an SslBundle from SslBundles, you can use SslBundle.getManagers() to get any KeyManagerFactory and TrustManagerFactory instances you need to configure the SSLContext.

@scottfrederick scottfrederick added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Jan 2, 2024
@syedyusufh
Copy link
Author

syedyusufh commented Jan 3, 2024

Hi @scottfrederick thanks for your inputs.

Like any enterprise we have both modern and legacy systems, so the custom TrustStrategy is a much needed one. The default SSL behavior out-of-box does NOT fit every system :(

Ssl Bundles solve the problem of application restart to update the application's Ssl Context due to the underlying certificate change and this is an awesome feature in a Microservices environment where multiple applications are run.

but I don't think Spring Boot should do anything more to make this easy to do so that user's don't mistakenly disable verification in production applications.

Spring Boot framework today provides options to configure your own TrustStrategy when setting up the SSL either via Apache Http or Netty implementations. For instance, we have out of framework implementations like InSecureTrustManagerFactory though with a warning and a disclaimer.

Once you get an SslBundle from SslBundles, you can use SslBundle.getManagers() to get any KeyManagerFactory and TrustManagerFactory instances you need to configure the SSLContext

Can we get the Ssl Bundle benefit of dynamic reloading of Ssl Context if the framework managed KeyManagerFactory and TrustManagerFactory are overridden?

Thanks

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 3, 2024
@scottfrederick
Copy link
Contributor

@syedyusufh I'm afraid it's still not completely clear what you're trying to accomplish. It seems that you are mostly concerned with configuring SSL for client connections. Reloading of SSL material with SSL bundles is only supported for server-side connections when using Tomcat or Netty as an embedded web server, so your questions about reloading the SSL context would not apply to your client connections.

I think we would make more progress on this discussion if we had a small code sample of what you are doing now. Can you provide a complete minimal application that demonstrates your use case, and share it with us by pushing it to a separate repository on GitHub or by zipping it and attaching it to this issue? That would make it much easier for us to see if there's anything we can add to our APIs for custom configuration of client connections.

@scottfrederick scottfrederick added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Jan 3, 2024
@syedyusufh
Copy link
Author

Reloading of SSL material with SSL bundles is only supported for server-side connections when using Tomcat or Netty as an embedded web server, so your questions about reloading the SSL context would not apply to your client connections

I got it now. Sorry, I was with the impression Ssl Bundle applicable components are all reloadable by default.

Kindly consider allowing an option to customize the TrustStrategy for client connections when we use Ssl Bundles

Thanks

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 4, 2024
@philwebb philwebb added the for: team-meeting An issue we'd like to discuss as a team to make progress label Jan 8, 2024
@scottfrederick scottfrederick added the theme: http-client-config Issues related to configuration of HTTP clients label Jan 9, 2024
@philwebb philwebb removed the for: team-meeting An issue we'd like to discuss as a team to make progress label Jan 10, 2024
@guybedo
Copy link

guybedo commented May 30, 2024

@syedyusufh i'm a bit late to the party, but i had a similar situation i think where i needed to connect to a https server.
I needed to provide client cert to connect to the server and needed to accept the server's self signed cert.

It wasn't possible to customize the SSLBundle trustmanagers / trustmanagerfactory so i ended up using the SSLBundle only to load the keys from the files. I didn't use it to build my RestTemplate and initialized the SSLContext with the SSLBundle's KeyManager[].

So, instead of:

SslBundle sslBundle = sslBundles.getBundle("rest");

return builder
    .setSslBundle(sslBundle)
    .messageConverters(converters)
    .build();

i did:

SslBundle sslBundle = sslBundles.getBundle("rest");
KeyManager[] keyManagers = sslBundle.getManagers().getKeyManagers();
SslUtils.configureDefaultSslSockerFactory(keyManagers);
return builder
    .messageConverters(converters)
    .build();

with SSLUtils:

public class SslUtils {

    public static TrustManager[] trustAllCerts() {
        return new TrustManager[] {
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }

                public void checkClientTrusted(
                    java.security.cert.X509Certificate[] certs,
                    String authType) {
                }

                public void checkServerTrusted(
                    java.security.cert.X509Certificate[] certs,
                    String authType) {
                }
            }
        };

    }

    public static void configureDefaultSslSockerFactory(KeyManager[] keyManagers) {
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(keyManagers, trustAllCerts(), new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        }
    }
}

@scottfrederick
Copy link
Contributor

I am still of the opinion that Spring Boot should not have a built-in ability to disable hostname verification or otherwise configure insecure connections. Users can do this now by creating their own client connections as has been mentioned above and demonstrated by @guybedo. We could make it simpler to customize a connection that has been created by Spring Boot, which is also suggested more generally in #39035. I'll close this issue as a duplicate.

@scottfrederick scottfrederick closed this as not planned Won't fix, can't repro, duplicate, stale Jul 16, 2024
@scottfrederick scottfrederick added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided theme: http-client-config Issues related to configuration of HTTP clients labels Jul 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

7 participants