Skip to content
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

Fix resteasy-reactive-client hostname verification default #32932

Conversation

polarctos
Copy link
Contributor

Since introduction of the setting verifyHost in 2.15.0.Final the hostname verification was disabled by default for the resteasy-reactive-client, as the default value for boolean in Java (primitive) is false.
gsmet@941d3a6#diff-28d8221e6b920ee90f85249d3c250b932c207d6b2099fc9377984d7f550fe28d

A better configuration name value would have been a negated name like disableHostnameVerification, but renaming it is no longer possible as it would break compatibility.

This disabled default currently makes the reactive client vulnerable to MITM attacks.
E.g. the following rest client builder from the documentation with quarkus-rest-client-reactive-jackson is vulnerable, as it does not fail during the SSL handshake:

RestClientBuilder.newBuilder()
    .baseUri(URI.create("https://wrong.host.badssl.com"))
    .build(WrongHostClient.class);

The expected exception has the cause javax.net.ssl.SSLHandshakeException. The test case ExternalWrongHostTestCase.java currently only tests the disabling of hostname verification but not for a default secure behaviour.

In the meantime setting the config explicitly is a workaround e.g. with quarkus.rest-client.verify-host=true.
This enables hostname verification again also for the reactive client. But the default of Quarkus should instead be secure!

This change now adds a proper default both in the configuration and assigns safe initial values for the fields in the reactive client builder implementation.

Both custom HostnameVerifier and SSLContext are currently not supported by resteasy-reactive-client.
This is documented as known limitations.

This change also aligns the implementation for both to the already present state for SSLContext.
It makes the builder fail when HostnameVerifier is tried to be configured. The benefit is that it fails as early as
currently possible and not only when the custom hostname verification would be needed later on.

The general need for the configuration option of a custom hostname verifier still stays relevant, as it was also requested in #27901. Currently just having the possibility to completely disable hostname verification is preventing the chance to supply a suitable customised hostname verifier that implements custom verification rules.

@polarctos polarctos marked this pull request as ready for review April 26, 2023 23:08
@gastaldi gastaldi requested review from geoand, Sgitario and famod April 26, 2023 23:40
Copy link
Contributor

@Sgitario Sgitario left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@quarkus-bot

This comment has been minimized.

@geoand
Copy link
Contributor

geoand commented Apr 27, 2023

The test failures are definitely related

polarctos added a commit to polarctos/quarkus that referenced this pull request Apr 27, 2023
polarctos added a commit to polarctos/quarkus that referenced this pull request Apr 27, 2023
On the rest-client-reactive settings a custom hostname
verifier is currently not supported. Adapted the tests
accordingly as the builder fails early now throwing
UnsupportedOperationException.

For quarkusio#32932 (comment)
@polarctos
Copy link
Contributor Author

The test failures are definitely related

@geoand

Sorry for that. Did not expect there to be tests for an unsupported feature.
I now removed the unsupported config tests for setting a hostnameVerifier.

On the rest-client-reactive config a custom hostname verifier was also before not supported, but did not throw an exception. Adapted the tests accordingly as the builder fails early now throwing UnsupportedOperationException.

The general discussion if failing here with an exception makes sense is discussed here: #32932 (comment)

In short: It should be the same behaviour for both unsupported features of the rest-client-reactive of HostnameVerifier and SSLContext.
Long term it would actually make sense to try to implement them, as they are part of the MP RestClientBuilder API.

@polarctos
Copy link
Contributor Author

polarctos commented Apr 27, 2023

Should a CVE be opened for this for the affected versions so that affected users are notified by scanners?

The actual weakness would be local to default false value of verifyHost
in org.jboss.resteasy.reactive.client.impl.ClientBuilderImpl
from io.quarkus.resteasy.reactive:resteasy-reactive-client.

From first sight the affected versions include: >= 2.15.0.Final <= 3.0.1.Final

At least for other products CVEs were sometimes opened fur such trivial things,
e.g. where in the defaults it is running curl -k.

Applicable CWEs:
https://cwe.mitre.org/data/definitions/297.html / https://cwe.mitre.org/data/definitions/295.html
https://cwe.mitre.org/data/definitions/453.html

@geoand
Copy link
Contributor

geoand commented Apr 27, 2023

As I have 0️⃣ time for at least the next week, I'll leave this up to @Sgitario and @sberyozkin

@Sgitario
Copy link
Contributor

Should a CVE be opened for this for the affected versions so that affected users are notified by scanners?

The actual weakness would be local to default false value of verifyHost in org.jboss.resteasy.reactive.client.impl.ClientBuilderImpl from io.quarkus.resteasy.reactive:resteasy-reactive-client.

From first sight the affected versions include: >= 2.15.0.Final <= 3.0.1.Final

At least for other products CVEs were sometimes opened fur such trivial things, e.g. where in the defaults it is running curl -k.

Applicable CWEs: https://cwe.mitre.org/data/definitions/297.html / https://cwe.mitre.org/data/definitions/295.html https://cwe.mitre.org/data/definitions/453.html

This sounds reasonable to me +1

@quarkus-bot

This comment has been minimized.

@polarctos polarctos force-pushed the fix/resteasy-reactive-client-hostname-verification branch from 75e9b90 to d9477f3 Compare April 29, 2023 16:25
@polarctos
Copy link
Contributor Author

I added a test now to assert that certificate host name verification is now enabled by default and working.

Build is also green now, based on the GitHub actions in the forked repository.

@geoand
Copy link
Contributor

geoand commented Apr 29, 2023

cc @Sgitario

@quarkus-bot

This comment has been minimized.

Copy link
Contributor

@Sgitario Sgitario left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good to me.
Though, there are still some custom hostname verifier classes that should be deleted now:

  • MyHostnameVerifier1 and MyHostnameVerifier2 in RestClientCDIDelegateBuilderTest
  • MyHostnameVerifier in HelloClientWithBaseUri

Also, squash all the commits, so we can proceed with merging these changes.

Many thanks!

polarctos added 2 commits May 2, 2023 20:31
Both custom HostnameVerifier and SSLContext are currently not
supported by resteasy-reactive-client. This is documented as
known limitations.

This change aligns the implementation to the already present state
for SSLContext. It makes the builder fail when HostnameVerifier is
tried to be configured. The benefit is that it fails as early as
currently possible and not only when the custom hostname verification
would be needed later on.

Switch both to UnsupportedOperationException.

On the rest-client-reactive settings a custom hostname
verifier is currently not supported. Adapted the tests
accordingly as the builder fails early now throwing
UnsupportedOperationException.
Since introduction of the setting 'verifyHost' the hostname
verification was disabled by default for the resteasy-reactive-client,
as the default value for boolean (primitive) is false.

This disabled default makes the reactive client vulnerable to MITM
attacks. In the meantime setting the config explicitly is a workaround
e.g. with 'quarkus.rest-client.verify-host=true'.

This change now adds a proper default both in the configuration and
for the field in the reactive client builder implementation.

Add test case for enabled host verification default
@polarctos polarctos force-pushed the fix/resteasy-reactive-client-hostname-verification branch from d9477f3 to 18f6f4c Compare May 2, 2023 18:32
@polarctos
Copy link
Contributor Author

Though, there are still some custom hostname verifier classes that should be deleted now:

  • MyHostnameVerifier1 and MyHostnameVerifier2 in RestClientCDIDelegateBuilderTest
  • MyHostnameVerifier in HelloClientWithBaseUri

Also, squash all the commits, so we can proceed with merging these changes.

@Sgitario I removed the unused hostname verifier classes from the tests now.

I squashed it down to two commits, but these two are actually independent of each other:

  • Fail on attempt to set custom hostname verifier
  • Enabling hostname verification by default

From my perspective, only the second commit for enabling the hostname verification is necessary as a security fix backport to other branches, as it fixes the current vulnerability.

@quarkus-bot
Copy link

quarkus-bot bot commented May 3, 2023

✔️ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

@polarctos
Copy link
Contributor Author

I think the pull request is now ready to be merged.

@Sgitario Sgitario requested a review from gastaldi May 4, 2023 05:13
@Sgitario
Copy link
Contributor

Sgitario commented May 4, 2023

@gastaldi would you mind a final review of this one and merging it if you're ok with it? Thanks!

@gastaldi gastaldi requested a review from sberyozkin May 4, 2023 11:30
@gastaldi
Copy link
Contributor

gastaldi commented May 4, 2023

@Sgitario it looks good to me but I'll let @sberyozkin have the final say on this 😉

@sberyozkin
Copy link
Member

sberyozkin commented May 5, 2023

Hi, should this PR check if quarkus.tls.trust-all is configured and if yes, prefer quarkus.tls.trust-all ? This is how OIDC client code is configured, so that if for example, OIDC protected endpoint is using OIDC reactive token propagation which relies on Resteasy Reactive client, the hostname verification can be configured with a single property, as opposed to configuring it twice

@sberyozkin
Copy link
Member

I suppose it can be handled in a follow up PR. @polarctos would you be OK with opening a new issue related to checking quarkus.tls.trust-all ? Thanks

@Sgitario
Copy link
Contributor

Sgitario commented May 5, 2023

Hi, should this PR check if quarkus.tls.trust-all is configured and if yes, prefer quarkus.tls.trust-all ? This is how OIDC client code is configured, so that if for example, OIDC protected endpoint is using OIDC reactive token propagation which relies on Resteasy Reactive client, the hostname verification can be configured with a single property, as opposed to configuring it twice

if 'verify-hostis true, buttrust-allis true, then theverify-host` will be turned off:

So, I think it's fine how it is now.

@gastaldi gastaldi merged commit 1d99246 into quarkusio:main May 6, 2023
@quarkus-bot quarkus-bot bot added this to the 3.1 - main milestone May 6, 2023
@gsmet gsmet modified the milestones: 3.1 - main, 3.0.3.Final May 9, 2023
@gsmet gsmet modified the milestones: 3.0.3.Final, 2.16.8.Final Jun 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants