Skip to content

[Java] Add generateInsecureTlsHook option to omit the trust-all-certificates hook (jersey2/jersey3) - #24786

Open
K3vChan wants to merge 2 commits into
OpenAPITools:masterfrom
K3vChan:java-optional-insecure-tls-hook
Open

[Java] Add generateInsecureTlsHook option to omit the trust-all-certificates hook (jersey2/jersey3)#24786
K3vChan wants to merge 2 commits into
OpenAPITools:masterfrom
K3vChan:java-optional-insecure-tls-hook

Conversation

@K3vChan

@K3vChan K3vChan commented Aug 26, 2026

Copy link
Copy Markdown

Fixes #24785

The jersey2 and jersey3 ApiClient templates unconditionally emit
disableCertificateValidation(), which builds an X509TrustManager with empty
checkClientTrusted/checkServerTrusted bodies and installs it into the
SSLContext. CodeQL reports this as java/insecure-trustmanager at high
severity, which fails the code scanning check on any PR that adds or touches the
generated client. Sonar's java:S4830 flags the same pattern.

The method is a protected opt-in hook — nothing in the generated client calls
it, and the javadoc on customizeClientBuilder tells you to override and invoke
it if you want it. But analysers flag code as written, not as reached, so
projects that commit their generated client (or scan target/) carry a
high-severity alert for a method they never use, with no way to opt out today:

  • no configOption gates the block — it is unconditional template text;
  • suppression comments do not survive regeneration;
  • .openapi-generator-ignore excludes whole files, and ApiClient is the class
    you configure, so it cannot be skipped.

What this changes

Adds a generateInsecureTlsHook option that gates the method, the javadoc lines
that point at it, and the seven imports that become unused without it
(SSLContext, TrustManager, X509TrustManager, X509Certificate,
SecureRandom, KeyManagementException, NoSuchAlgorithmException).

It defaults to true, so generated output is unchanged. Anyone who
overrides customizeClientBuilder and calls the hook keeps compiling. Opting
out is explicit:

<configOptions>
  <generateInsecureTlsHook>false</generateInsecureTlsHook>
</configOptions>

Scope

Limited to jersey2 and jersey3. okhttp-gson contains a similar trust-all
X509TrustManager, but there it sits inside applySslSettings() behind the
runtime verifyingSsl field, which has a public setVerifyingSsl(boolean)
setter and is a documented feature. Gating that would be a breaking change, so
it is left alone. native, apache-httpclient and resttemplate do not emit
the block at all.

Testing

  • Added testInsecureTlsHookGeneratedByDefault and
    testInsecureTlsHookOmittedWhenDisabled to JavaClientCodegenTest, both run
    against jersey2 and jersey3 via a data provider (4 cases). The second
    asserts the method, the X509TrustManager and each of the seven imports are
    absent.
  • Full JavaClientCodegenTest: 278 tests, 0 failures.
  • Regenerated every bin/configs/java*.yaml sample: no diff, confirming
    the default preserves current output.
  • Generated jersey2 and jersey3 clients with the option off and confirmed no
    residue of the method or its imports, and that spacing around the removal
    stays correct (one blank line between the neighbouring members).
  • Regenerated generator docs.

PR checklist

  • Read the contribution guidelines.
  • Ran the build and updated samples and docs:
    ./mvnw clean package
    ./bin/generate-samples.sh ./bin/configs/java*.yaml
    ./bin/utils/export_docs_generators.sh
    
    Samples produced no diff, as expected for a default-preserving change. Docs
    were regenerated and are included.
  • Filed against master as a non-breaking change.
  • @mentioning the technical committee for the affected libraries: @xhh
    (Java Jersey2), and @bbdouglas @wing328 as Java maintainers, in case you would
    prefer a different option name or a different default.

Summary by cubic

Adds a generateInsecureTlsHook option for jersey2/jersey3 so the generated ApiClient no longer has to include the trust-all disableCertificateValidation hook that static analyzers flag as java/insecure-trustmanager (fixes #24785).

The option defaults to true, so generated output is unchanged; docs previously advertised a false default because the CLI option wasn't explicitly registered with one, which is now fixed. Setting it to false removes the hook, its javadoc, and the seven imports that become unused. okhttp-gson is left untouched because its equivalent is a live runtime feature behind setVerifyingSsl, not a dead method.

New Features

  • generateInsecureTlsHook is a new configOptions boolean for jersey2/jersey3, defaulting to true.
  • Regenerating all existing Java samples produces no diff.

Written for commit 8d3bace. Summary will update on new commits.

Review in cubic

The jersey2 and jersey3 ApiClient templates always emit
disableCertificateValidation(), which installs an X509TrustManager with
empty checkClientTrusted/checkServerTrusted bodies. CodeQL reports it as
java/insecure-trustmanager at high severity, which fails the code scanning
check on any PR touching the generated client.

The method is a protected opt-in hook that nothing in the generated client
calls, but analysers flag code as written rather than as reached, so
projects carry a high-severity alert for a method they never use. There is
currently no way to opt out: no option gates the block, suppression
comments do not survive regeneration, and .openapi-generator-ignore cannot
skip ApiClient because it is the class you configure.

Add a generateInsecureTlsHook option gating the method, the javadoc that
points at it, and the seven imports that become unused without it.

It defaults to true, so generated output is unchanged and existing
subclasses that call the hook keep compiling. Regenerating every java*
sample produces no diff.

Scoped to jersey2 and jersey3. okhttp-gson contains a similar trust-all
block, but there it sits inside applySslSettings() behind the runtime
verifyingSsl field, which has a public setVerifyingSsl setter. That is a
live feature rather than a dead hook, so removing it would be a breaking
change and is left alone.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/generators/java-microprofile.md">

<violation number="1" location="docs/generators/java-microprofile.md:59">
P2: This option is documented for java-microprofile but is a no-op there. java-microprofile (JavaMicroprofileServerCodegen) extends JavaClientCodegen, so the unconditionally-registered CliOption at JavaClientCodegen.java:287 propagates here and to every other Java generator, yet only the jersey2/jersey3 ApiClient mustache templates consult generateInsecureTlsHook. Users of this generator see an option that does nothing, contradicting the PR's stated jersey2/jersey3 scope. Add the CliOption (and its additionalProperties defaulting) only for the jersey2/jersey3 libraries, or otherwise filter it from generators whose templates never read it.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread docs/generators/java-microprofile.md Outdated
|generateBuilders|Whether to generate builders for models| |false|
|generateClientAsBean|For resttemplate, restclient and webclient, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).| |false|
|generateConstructorWithAllArgs|whether to generate a constructor for all arguments| |false|
|generateInsecureTlsHook|Generate the ApiClient.disableCertificateValidation hook, which trusts all TLS certificates (default to true). Set to false to omit it, e.g. when static analysis flags the trust-all TrustManager it contains. Available on `jersey2`, `jersey3` libraries.| |false|

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: This option is documented for java-microprofile but is a no-op there. java-microprofile (JavaMicroprofileServerCodegen) extends JavaClientCodegen, so the unconditionally-registered CliOption at JavaClientCodegen.java:287 propagates here and to every other Java generator, yet only the jersey2/jersey3 ApiClient mustache templates consult generateInsecureTlsHook. Users of this generator see an option that does nothing, contradicting the PR's stated jersey2/jersey3 scope. Add the CliOption (and its additionalProperties defaulting) only for the jersey2/jersey3 libraries, or otherwise filter it from generators whose templates never read it.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/generators/java-microprofile.md, line 59:

<comment>This option is documented for java-microprofile but is a no-op there. java-microprofile (JavaMicroprofileServerCodegen) extends JavaClientCodegen, so the unconditionally-registered CliOption at JavaClientCodegen.java:287 propagates here and to every other Java generator, yet only the jersey2/jersey3 ApiClient mustache templates consult generateInsecureTlsHook. Users of this generator see an option that does nothing, contradicting the PR's stated jersey2/jersey3 scope. Add the CliOption (and its additionalProperties defaulting) only for the jersey2/jersey3 libraries, or otherwise filter it from generators whose templates never read it.</comment>

<file context>
@@ -56,6 +56,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
 |generateBuilders|Whether to generate builders for models| |false|
 |generateClientAsBean|For resttemplate, restclient and webclient, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).| |false|
 |generateConstructorWithAllArgs|whether to generate a constructor for all arguments| |false|
+|generateInsecureTlsHook|Generate the ApiClient.disableCertificateValidation hook, which trusts all TLS certificates (default to true). Set to false to omit it, e.g. when static analysis flags the trust-all TrustManager it contains. Available on `jersey2`, `jersey3` libraries.| |false|
 |gradleProperties|Append additional Gradle properties to the gradle.properties file| |null|
 |groupId|groupId in generated pom.xml| |org.openapitools|
</file context>

Comment thread docs/generators/java.md Outdated
CliOption.newBoolean(opt, description) records false, so the generated
docs tables and config-help reported a default of false while processOpts
treats an absent property as true. For an option controlling whether a
trust-all TrustManager is emitted, advertising the wrong default is worse
than for most, so pass the default explicitly.
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.

[REQ] [Java] Option to omit the trust-all-certificates hook from the generated ApiClient (jersey2/jersey3/okhttp-gson)

2 participants