Core: Expose HostnameVerificationPolicy in TLSConfigurer#15500
Core: Expose HostnameVerificationPolicy in TLSConfigurer#15500adutra wants to merge 5 commits intoapache:mainfrom
Conversation
|
FYI @bryanck |
ad082ad to
2858de7
Compare
Alex, why would we allow such a verification to be bypassed, do you have some real world use case for this ? |
| awssdk-s3accessgrants = { module = "software.amazon.s3.accessgrants:aws-s3-accessgrants-java-plugin", version.ref = "awssdk-s3accessgrants" } | ||
| azuresdk-bom = { module = "com.azure:azure-sdk-bom", version.ref = "azuresdk-bom" } | ||
| bson = { module = "org.mongodb:bson", version.ref = "bson-ver"} | ||
| bouncycastle-bcpkix = { module = "org.bouncycastle:bcpkix-jdk18on", version.ref = "bouncycastle" } |
There was a problem hiding this comment.
Since this is new dependency, do we have to add the licence of this dependency to one of the LICENSE files in Iceberg?
There was a problem hiding this comment.
No, since it's used only in tests.
There was a problem hiding this comment.
Thanks for clarifying.
There was a problem hiding this comment.
that's good because bouncycastle complicates export rules, or at least due diligence
There was a problem hiding this comment.
I assumes the bouncycastle bcpkix is a transitive dep already pulled in by the mockerserver lib. is the purpose here just to upgrade the version?
There was a problem hiding this comment.
Very good question! Short answer: yes.
MockServer does bring BouncyCastle transitively — bcprov, bcpkix, and bcutil – but at version 1.72, which is somewhat old.
The problem is that other deps (Hadoop) bring bcprov 1.82, and Gradle resolves the conflict by upgrading bcprov to 1.82. But bcpkix and bcutil stay at 1.72, since nothing else declares a higher version. This creates a mismatch: bcpkix 1.72 + bcprov 1.82 = NoClassDefFoundError.
I only upgraded bcpkix here, because that is enough for running the TLS tests. If you prefer, I can also explicitly upgrade bcutil.
There was a problem hiding this comment.
it is probably good to just ensure the same version for bouncycastle family of jars. That is the current practice. E.g., there is just one version number for the two jetty jars in the toml file.
There was a problem hiding this comment.
You are right: I implemented your suggestion.
You could find yourself in the situation where the catalog server has TLS enabled, and its certificate shows a SAN of e.g. (Please note: I mentioned |
|
And I forgot to mention: |
|
@bryanck since you introduced |
Apache HttpClient 5.4 introduced a new component: `HostnameVerificationPolicy`, which determines whether hostname verification is done by the JSSE provider (at socket level, during TLS handshake), the HttpClient (after TLS handshake), or both. This change exposes `HostnameVerificationPolicy` in `TLSConfigurer`. This component is particularly useful when attempting to bypass hostname verification, e.g. by using the `NoopHostnameVerifier`. The default policy is set to `BOTH`, which produces the same result as before.
2858de7 to
6e3cfb8
Compare
|
Update: I was able to find the exact change that caused this regression: In 1.10 we use httpclient5 version 5.5, where the public DefaultClientTlsStrategy(
final SSLContext sslContext,
final String[] supportedProtocols,
final String[] supportedCipherSuites,
final SSLBufferMode sslBufferManagement,
final HostnameVerifier hostnameVerifier) {
this(sslContext, supportedProtocols, supportedCipherSuites, sslBufferManagement, HostnameVerificationPolicy.CLIENT, hostnameVerifier);
}But in 1.11 we upgraded httpclient5 to version 5.6, where the same constructor becomes: public DefaultClientTlsStrategy(
final SSLContext sslContext,
final String[] supportedProtocols,
final String[] supportedCipherSuites,
final SSLBufferMode sslBufferManagement,
final HostnameVerifier hostnameVerifier) {
this(sslContext, supportedProtocols, supportedCipherSuites, sslBufferManagement, null, hostnameVerifier);
}Passing So, this is imho clearly a regression, and in fact the default value for default HostnameVerificationPolicy hostnameVerificationPolicy() {
return HostnameVerificationPolicy.CLIENT;
}I will change that. @singhpk234 could you please add this to the 1.11 milestone? Now I'm really convinced it's a regression. |
|
@danielcweeks and @singhpk234 : as requested, I created an issue to better explain why I think we have a regression and how this PR fixes it: #15598. PTAL 🙏 |
I am wondering about the default value of HostnameVerificationPolicy.CLIENT. I know the purpose is maintain the same behavior. Unit test can configure Is |
| exclude group: 'junit' | ||
| } | ||
| testImplementation libs.awaitility | ||
| testImplementation libs.bouncycastle.bcpkix |
There was a problem hiding this comment.
I think it's worth at least adding a comment on why these dependencies are being added, since it's not obvious
Best to lock down and require relaxation in deployments than to unlock and regret it. More formally CWE-1188: Initialization of a Resource with an Insecure Default |
|
Can you send an email to dev@ to get broader feedback? It might be ok introduce a slight behavior change. Most production use cases probably should use DNS anyway. For IP address usage, users can add the IP address to the cert SAN. This is the only question I have for this PR. Exposing |
Fixes #15598.
This change exposes
HostnameVerificationPolicyinTLSConfigurer. The default policy is set toCLIENT.I also added a unit test that intentionally uses a custom hostname verifier that is incompatible with JSSE hostname verification strategies. Thus, the test cannot pass unless the verification policy is set to
CLIENT.