I just had a look in the hadoop code https://github.com/apache/hadoop/blob/fb8932a727f757b2e9c1c61a18145878d0eb77bd/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/SSLHostnameVerifier.java
thiis is declared as "Copied from the not-yet-commons-ssl project at http://juliusdavies.ca/commons-ssl/",... "Inspired by Sebastian Hauer's original StrictSSLProtocolSocketFactory in the HttpClient "contrib" repository." commons-ssl leads to https://cwiki.apache.org/confluence/display/incubator/CommonsSSLProposal Ultimately it allows you configure a hadoop cluster with x.509 and certificate management needed to have encrypted network traffic, shuffle etc. private HostnameVerifier getHostnameVerifier(Configuration conf) throws GeneralSecurityException, IOException { return getHostnameVerifier(StringUtils.toUpperCase( conf.get(SSL_HOSTNAME_VERIFIER_KEY, "DEFAULT").trim())); } public static HostnameVerifier getHostnameVerifier(String verifier) throws GeneralSecurityException, IOException { HostnameVerifier hostnameVerifier; if (verifier.equals("DEFAULT")) { hostnameVerifier = SSLHostnameVerifier.DEFAULT; } else if (verifier.equals("DEFAULT_AND_LOCALHOST")) { hostnameVerifier = SSLHostnameVerifier.DEFAULT_AND_LOCALHOST; } else if (verifier.equals("STRICT")) { hostnameVerifier = SSLHostnameVerifier.STRICT; } else if (verifier.equals("STRICT_IE6")) { hostnameVerifier = SSLHostnameVerifier.STRICT_IE6; } else if (verifier.equals("ALLOW_ALL")) { hostnameVerifier = SSLHostnameVerifier.ALLOW_ALL; } else { throw new GeneralSecurityException("Invalid hostname verifier: " + verifier); } return hostnameVerifier; } That code gets minimal maintenance and shows its age (who needs strict IE6 compatibility?) and I suspect DEFAULT is what everyone uses. Which is good as httpclient reads the resource mozilla/public-suffix-list.txt to have an up to date list of country codes and other toplevel domains where you mustn't trust wildcard certificates (*.co.uk etc). What I would say looking at the code is *"you** need to understand real world SSL to write a hostname verifier you can trust". *if you don't have that knowledge, your system is probably less secure than you think. On Mon, 30 Mar 2026 at 20:17, Steven Wu <[email protected]> wrote: > I agree with Russell's point. Since we don't expose BOTH before, we can > keep the restricted API for now. Users must know what they are doing from > security perspective when they choose to override the hostname verifier. > > If there is a clear need to expose "HostnameVerificationPolicy.BOTH" in > the future, we can add the new API then. It is always easier to open up new > APIs than to remove them. > > On Mon, Mar 30, 2026 at 11:32 AM Russell Spitzer < > [email protected]> wrote: > >> Did a bit of Github Searching with Cursor >> >> It gives me 7 Hits of real use cases BOTH mode in non-forks >> >> ----- >> >> HostnameVerificationPolicy.BOTH — All real-world usages on GitHub >> (excluding httpcomponents-client itself and forks) >> >> Passing library default explicitly (no custom verifier logic) >> - ch4mpy/spring-addons: Spring Boot REST helpers — TrustAll + default >> verifier, BOTH is redundant >> - openziti/ziti-sdk-jvm: Zero-trust networking SDK — copied library >> internals verbatim >> - eryanwcp/ec: Chinese enterprise framework — default verifier, just >> being explicit >> - dmandalidis/docker-client: Docker API client — passes Docker cert >> store's full verifier through >> >> Misuse (BOTH contradicts intent) >> - dannguyenmessi1705/Spring (2 files): Personal Spring learning >> projects — BOTH + NoopHostnameVerifier, trying to disable verification but >> BOTH keeps JSSE active >> - kadukm/five-letters: Personal word-game crawler — same bug, BOTH + >> NoopHostnameVerifier >> >> Test code only >> - dtreskunov/easyssl: TLS testing library — default verifier in >> integration test helper >> >> >> >> On Mon, Mar 30, 2026 at 1:13 PM Russell Spitzer < >> [email protected]> wrote: >> >>> We never exposed BOTH before, so I'm not sure why we would do so now. >>> I'm not convinced >>> that there is a theoretical use case we are missing since no one asked >>> for this before, >>> and the BOTH option has existed in the underlying library for years. I'm >>> very conservative >>> about opening new interface points when we don't have demand. >>> >>> In this case we are also specifically trying to avoid a regression, so >>> this would be the wrong time >>> to expose a new interface and set of functionality. >>> >>> We can always follow up with a new proposal if it's something folks >>> really want, but I don't >>> think we should open it up just because it's possible. >>> >>> On Mon, Mar 30, 2026 at 12:12 PM Steven Wu <[email protected]> wrote: >>> >>>> If a user wants to customize the hostname verification, is it additive >>>> to the JSSE verification (BOTH) or does it require a totally independent >>>> verification algorithm (CLIENT)? This is probably where it boils down. >>>> >>>> Russell's suggestion aligns with the latter camp (CLIENT). A user must >>>> know what they are doing before overriding the hostname verification >>>> algorithm. >>>> >>>> On Mon, Mar 30, 2026 at 8:47 AM Alexandre Dutra <[email protected]> >>>> wrote: >>>> >>>>> Hi all, >>>>> >>>>> I have some reservations about Russell's suggestion. >>>>> >>>>> I believe the HttpClient developers introduced the BOTH value for a >>>>> compelling reason. This is likely due to the inherent complexity of >>>>> implementing a robust HostnameVerifier from scratch. The task involves >>>>> non-trivial aspects like manually parsing SANs, handling complex >>>>> wildcard matching, managing internationalized domain names, and >>>>> accounting for legacy CN fallbacks. >>>>> >>>>> Consider a custom verifier intended to restrict an HTTP client to >>>>> specific internal subdomains; it's very easy to write one: >>>>> >>>>> HostnameVerifier myVerifier = (hostname, session) -> { >>>>> return hostname.endsWith(".internal.mycompany.com"); >>>>> }; >>>>> >>>>> Used with BOTH, this verifier does the job. If used with CLIENT, >>>>> however, it creates a massive security vulnerability because standard >>>>> JSSE validation is bypassed. >>>>> >>>>> IOW, I think there is value in using BOTH, and there is value in >>>>> exposing the HostnameVerificationPolicy. >>>>> >>>>> Thanks, >>>>> Alex >>>>> >>>>> On Thu, Mar 26, 2026 at 2:16 AM Russell Spitzer >>>>> <[email protected]> wrote: >>>>> > >>>>> > I wouldn’t even expose the interface for downstream extensions. We >>>>> currently don’t have >>>>> > any implementations that expect this to be anything other than >>>>> client and >>>>> > I’m not sure we want to encourage folks to use “both.” >>>>> > >>>>> >> >>>>> >> On Wed, Mar 25, 2026 at 10:02 AM Alexandre Dutra <[email protected]> >>>>> wrote: >>>>> >>> >>>>> >>> Hi Russell, >>>>> >>> >>>>> >>> > I can't think of a situation where it would make sense to use a >>>>> custom client verifier and the JSSE verifier. Running two verifiers just >>>>> means the stricter one wins and the less strict one is a noop. >>>>> >>> >>>>> >>> I wouldn't say a noop, it could perform additional hostname >>>>> validation >>>>> >>> that goes beyond checking the SANs in the certificate. >>>>> > >>>>> > >>>>> > That's the rub here. If the custom implementation goes beyond >>>>> checking the SANs then why doesn't it also just check the SANs. If we >>>>> > didn't, we end up with this design where the custom verifier only >>>>> does part of the job and relies >>>>> > on another component which can change on library updates to do the >>>>> rest. The purpose here is to >>>>> > provide an alternative to the default, so why write one that still >>>>> depends on the default running alongside it? >>>>> > >>>>> >>> >>>>> >>> > My solution would be to default hostNameVerifier to "null" >>>>> instead of the current non-null response and always pass through CLIENT >>>>> when hostNameVerifier is explicitly defined. >>>>> >>> >>>>> >>> The issue is that the hostname verifier is *always* defined. >>>>> >>> TLSConfigurer.hostnameVerifier() by default returns >>>>> >>> HttpsSupport.getDefaultHostnameVerifier(). While it's technically >>>>> >>> possible to override the method and return null, I doubt anyone is >>>>> >>> doing this because the method is not explicitly annotated as >>>>> >>> @Nullable, and returning null would look like an API misuse. That's >>>>> >>> why I went with CLIENT, initially. >>>>> > >>>>> > >>>>> > >>>>> > That's what i'm saying we should change. If we change our default >>>>> implementation to return null >>>>> > i think that's better. We could potentially break folks who are >>>>> checking this return value and >>>>> > assuming it isn't null but I think that's probably better than >>>>> continuing with the imho incorrect >>>>> > default. >>>>> > >>>>> > Something like >>>>> > >>>>> > public interface TLSConfigurer { >>>>> > default HostnameVerifier hostnameVerifier() { >>>>> > return null; >>>>> > } >>>>> > } >>>>> > >>>>> > >>>>> > TLSConfigurer tlsConfigurer = loadTlsConfigurer(properties); >>>>> > if (tlsConfigurer != null) { >>>>> > HostnameVerifier hostnameVerifier = tlsConfigurer.hostnameVerifier(); >>>>> > connectionManagerBuilder.setTlsSocketStrategy( >>>>> > new DefaultClientTlsStrategy( >>>>> > tlsConfigurer.sslContext(), >>>>> > tlsConfigurer.supportedProtocols(), >>>>> > tlsConfigurer.supportedCipherSuites(), >>>>> > SSLBufferMode.STATIC, >>>>> > hostnameVerifier != null >>>>> > ? HostnameVerificationPolicy.CLIENT >>>>> > : HostnameVerificationPolicy.BUILTIN, >>>>> > hostnameVerifier)); >>>>> > } >>>>> > >>>>> > Anyone overriding hostnameVerifier get's client, everyone else gets >>>>> the deault and "BUILTIN" >>>>> > >>>>> >>> >>>>> >>> >>>>> >>> >>>>> >>> That said if we really want to go down that route, I don't mind >>>>> >>> re-implementing hostnameVerificationPolicy() as per your >>>>> suggestion: >>>>> >>> >>>>> >>> default HostnameVerificationPolicy hostnameVerificationPolicy() { >>>>> >>> return hostnameVerifier() == null >>>>> >>> ? HostnameVerificationPolicy.BUILTIN >>>>> >>> : HostnameVerificationPolicy.CLIENT; >>>>> >>> } >>>>> >>> >>>>> >>> Thanks, >>>>> >>> Alex >>>>> >>> >>>>> >>> On Wed, Mar 25, 2026 at 6:24 PM Russell Spitzer >>>>> >>> <[email protected]> wrote: >>>>> >>> > >>>>> >>> > I don't think BOTH makes sense as a default and I'm not sure >>>>> it's actually more secure. >>>>> >>> > >>>>> >>> > If I have a custom TLS impl which overrides host name verifier, >>>>> I want to be using CLIENT mode. I can't >>>>> >>> > think of a situation where it would make sense to use a custom >>>>> client verifier and the JSSE verifier. Running >>>>> >>> > two verifiers just means the stricter one wins and the less >>>>> strict one is a noop. This means with "both" we can only use >>>>> >>> > a custom verifier that is stricter than the JSSE one. >>>>> >>> > >>>>> >>> > My suggestions would be to change the constructor to use the 6 >>>>> arg version for the constructor with an explicit CLIENT >>>>> >>> > when a verifier is explicitly set. >>>>> >>> > >>>>> >>> > If I have a custom TLS impl which doesn't override the host name >>>>> verifier, I don't want "BOTH or CLIENT", I want "BUILTIN". Any >>>>> >>> > client side verification is a waste. >>>>> >>> > >>>>> >>> > My solution would be to default hostNameVerifier to "null" >>>>> instead of the current non-null response and >>>>> >>> > always pass through CLIENT when hostNameVerifier is explicitly >>>>> defined. >>>>> >>> > >>>>> >>> > If we just always use BOTH won't we just end up breaking folks >>>>> who tried to put in custom verifiers? The whole >>>>> >>> > point I would think is that they are trying to use a verifier >>>>> which is more permissive than the JSSE one. >>>>> >>> > >>>>> >>> > So basically I would only support two paths for custom TLS >>>>> >>> > >>>>> >>> > 1) Custom host verifier = CLIENT >>>>> >>> > 2) No custom host verifier = BUILTIN >>>>> >>> > >>>>> >>> > I'm not sure I see a world where a user would want to specify >>>>> their own verification policy so I wouldn't really >>>>> >>> > expose that as an option at all. This would also simplify the >>>>> implementation of the PR a bit. >>>>> >>> > But if someone has such a use case, please let me know. >>>>> >>> > >>>>> >>> > On Wed, Mar 25, 2026 at 9:56 AM Eduard Tudenhöfner < >>>>> [email protected]> wrote: >>>>> >>> >> >>>>> >>> >> I think we should opt for the safer option and go with BOTH. >>>>> >>> >> >>>>> >>> >> On Wed, Mar 25, 2026 at 11:22 AM Alexandre Dutra < >>>>> [email protected]> wrote: >>>>> >>> >>> >>>>> >>> >>> +1 to using BOTH by default. >>>>> >>> >>> >>>>> >>> >>> Le mer. 25 mars 2026 à 00:55, Steven Wu <[email protected]> >>>>> a écrit : >>>>> >>> >>>> >>>>> >>> >>>> Are there any concerns about changing the hostname >>>>> verification policy default from CLIENT to BOTH (more secure) in the 1.11 >>>>> release? >>>>> >>> >>>> >>>>> >>> >>>> This is the last blocker for the 1.11.0 release. Let's decide >>>>> to unblock the release. Hopefully we can get 1.11.0 out before the summit. >>>>> >>> >>>> >>>>> >>> >>>> On Fri, Mar 20, 2026 at 12:02 PM Steven Wu < >>>>> [email protected]> wrote: >>>>> >>> >>>>> >>>>> >>> >>>>> I asked for a dev ML discussion for this. I will share why I >>>>> favor changing the default to HostnameVerificationPolicy.BOTH in the next >>>>> 1.11 release. >>>>> >>> >>>>> >>>>> >>> >>>>> * In the production environment, people should use the >>>>> hostname matching the SAN attribute in the certificate. The hostname could >>>>> be a DNS name, an IP address, or both. The certificate must be generated >>>>> with the proper Subject Alternative Name (SAN) matching its intended use. >>>>> While this is a slight behavior change for the 1.11 release, the practical >>>>> impact should be very small since production deployments probably use a >>>>> DNS >>>>> name anyway. >>>>> >>> >>>>> * For the unit test, Alex's PR #15598 provides the >>>>> customization to allow using the loopback IP address (127.0.0.1) with noop >>>>> hostname verification. >>>>> >>> >>>>> >>>>> >>> >>>>> BTW, this is the last blocking PR for version 1.11.0 >>>>> release. It will be great to reach a consensus soon. >>>>> >>> >>>>> https://github.com/apache/iceberg/milestone/59 >>>>> >>> >>>>> >>>>> >>> >>>>> >>>>> >>> >>>>> On Fri, Mar 20, 2026 at 11:43 AM Alexandre Dutra < >>>>> [email protected]> wrote: >>>>> >>> >>>>>> >>>>> >>> >>>>>> Hi all, >>>>> >>> >>>>>> >>>>> >>> >>>>>> Last week I opened an issue to report what I believe is a >>>>> regression >>>>> >>> >>>>>> in the HTTPClient when using TLS: >>>>> >>> >>>>>> >>>>> >>> >>>>>> https://github.com/apache/iceberg/issues/15598 >>>>> >>> >>>>>> >>>>> >>> >>>>>> I also opened a PR to fix it: >>>>> >>> >>>>>> >>>>> >>> >>>>>> https://github.com/apache/iceberg/pull/15500 >>>>> >>> >>>>>> >>>>> >>> >>>>>> The fix is basically to expose the >>>>> HostnameVerificationPolicy in the >>>>> >>> >>>>>> TLSConfigurer, and I think there is consensus on that. >>>>> >>> >>>>>> >>>>> >>> >>>>>> However I would like to have the community's opinion about >>>>> the default >>>>> >>> >>>>>> value we should use for the HostnameVerificationPolicy. >>>>> >>> >>>>>> >>>>> >>> >>>>>> We can either go with: >>>>> >>> >>>>>> >>>>> >>> >>>>>> - CLIENT, which reproduces the current behavior in 1.10 but >>>>> is less safe; or >>>>> >>> >>>>>> - BOTH, which introduces a behavioral change, but is the >>>>> safest option. >>>>> >>> >>>>>> >>>>> >>> >>>>>> What do you think? >>>>> >>> >>>>>> >>>>> >>> >>>>>> Thanks, >>>>> >>> >>>>>> Alex >>>>> >>>>
