Skip to content

fix(security): upgrade Jetty 11.0.26 -> 12.0.35 to fix CVE-2026-2332#2894

Open
srujana-kuntumalla wants to merge 7 commits into
apache:mainfrom
srujana-kuntumalla:fix/TIKA-CVE-2026-2332-jetty-upgrade
Open

fix(security): upgrade Jetty 11.0.26 -> 12.0.35 to fix CVE-2026-2332#2894
srujana-kuntumalla wants to merge 7 commits into
apache:mainfrom
srujana-kuntumalla:fix/TIKA-CVE-2026-2332-jetty-upgrade

Conversation

@srujana-kuntumalla

@srujana-kuntumalla srujana-kuntumalla commented Jun 16, 2026

Copy link
Copy Markdown

Summary

  • CVE-2026-2332 (CVSS 9.1 Critical, CWE-444): HTTP/1.1 request smuggling via improper chunk-extension parsing in Jetty. Affects Jetty 11.0.0–11.0.26. Jetty 11.x is EOL with no backport; fix is available in Jetty 12.0.33+.
  • Jetty 12.0.x requires Java 17, same minimum JVM version as this project — no Java upgrade needed.
  • CXF upgrade to 4.1.7 was previously blocked on Jetty 11; it is now unblocked (CXF 4.1.x targets Jetty 12).
  • SolrJ upgraded to 10.0.0 because SolrJ 9 embeds Jetty 11 HTTP client APIs that conflict with Jetty 12.

Changes

File Change
tika-parent/pom.xml jetty.version 11.0.26 → 12.0.35; rename http2-* artifacts to jetty-http2-*; cxf.version 4.0.11 → 4.1.7; solrj.version 9.10.1 → 10.0.0; centralise jakarta.servlet-api version management; use ${jetty.http2.version} in OSS Index exclusion
tika-server/tika-server-core/pom.xml Use renamed jetty-http2-server; add jakarta.servlet-api (Jetty 12 no longer bundles the EE9 servlet JAR; version managed in parent)
SolrEmitter.java, SolrPipesIterator.java Http2SolrClientHttpJettySolrClient, LBHttpSolrClientLBJettySolrClient (SolrJ 10 renames); proxy configured via native Jetty API (withProxyConfiguration), skipped when port is unset; non-basic auth schemes rejected early with TikaConfigException since HttpJettySolrClient only supports basic auth
tika-pipes-solr/pom.xml, tika-pipes-solr-integration-tests/pom.xml Add solr-solrj-jetty and solr-solrj-zookeeper (SolrJ 10 moved Jetty client and ZK classes to separate modules)
TikaPipesSolrTestBase.java Http2SolrClientHttpJettySolrClient
PipesBiDirectionalStreamingIntegrationTest.java PathResource (removed in Jetty 12) → ResourceHandler.setBaseResourceAsString()

Test plan

  • ./mvnw verify -pl tika-parent,tika-core,tika-server/tika-server-core -DskipTests — validate POM changes compile
  • ./mvnw test -pl tika-pipes/tika-pipes-plugins/tika-pipes-solr — Solr emitter/iterator unit tests
  • ./mvnw test -pl tika-grpc — gRPC streaming integration test with Jetty 12 HTTP server
  • ./mvnw verify -pl tika-integration-tests/tika-pipes-solr-integration-tests — Solr integration tests (requires Docker)

🤖 Generated with Claude Code

srujana-kuntumalla and others added 2 commits June 15, 2026 23:02
CVE-2026-2332 (CVSS 9.1, CWE-444): HTTP/1.1 request smuggling via improper
chunk-extension parsing. Jetty 11.x is EOL with no backport; the fix is in
Jetty 12.0.33+. Jetty 12.0.x requires Java 17, same minimum as this project.

Changes:
- tika-parent/pom.xml: jetty.version 11.0.26 -> 12.0.35; rename http2
  artifacts (http2-* -> jetty-http2-*); upgrade cxf.version 4.0.11 -> 4.1.7
  (CXF 4.1.x targets Jetty 12); upgrade solrj.version 9.10.1 -> 10.0.0
  (SolrJ 9 bundles Jetty 11 client APIs incompatible with Jetty 12)
- tika-server-core/pom.xml: use renamed jetty-http2-server; add
  jakarta.servlet-api 6.0.0 (Jetty 12 no longer bundles the EE9 servlet JAR)
- SolrEmitter.java, SolrPipesIterator.java: Http2SolrClient ->
  HttpJettySolrClient, LBHttpSolrClient -> LBJettySolrClient (SolrJ 10 renames)
- tika-pipes-solr/pom.xml, tika-pipes-solr-integration-tests/pom.xml: add
  solr-solrj-jetty (SolrJ 10 split Jetty client classes into a separate module)
- TikaPipesSolrTestBase.java: Http2SolrClient -> HttpJettySolrClient
- PipesBiDirectionalStreamingIntegrationTest.java: PathResource (removed in
  Jetty 12) -> ResourceHandler.setBaseResourceAsString()

Note: LBJettySolrClient no longer accepts Apache HttpClient; proxy/auth
configuration via HttpClientFactory needs follow-up work (marked with TODOs).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Compilation revealed that SolrJ 10 moved classes to new packages:
- HttpJettySolrClient, LBJettySolrClient: org.apache.solr.client.solrj.impl ->
  org.apache.solr.client.solrj.jetty
- SolrQuery: org.apache.solr.client.solrj -> org.apache.solr.client.solrj.request
- LBJettySolrClient.Builder now takes (HttpJettySolrClient, Endpoint...) in its
  constructor rather than a fluent withBaseEndpoints(); endpoints passed inline
- Proxy is now configured via HttpJettySolrClient.Builder.withProxyConfiguration()
  natively, removing the dependency on Apache HttpClient for proxy/auth
- CloudSolrClient.Builder.withInternalClientBuilder() confirmed present and used
  for the ZooKeeper path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@THausherr

Copy link
Copy Markdown
Contributor

here's what copilot wrote about the fail:

===

The failure is in tika-pipes-solr-integration-tests, specifically:

  • Test: org.apache.tika.pipes.solr.tests.TikaPipesSolr8ZkTest.testPipesIteratorWithSolrUrls
  • Error: ClassNotFoundException: org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider
  • Job: 81576009080
  • Ref: a8f8898752453ea5ccbbbcb264f1915159cc15c5
  • Workflow: .github/workflows/main-jdk17-build.yml

Root cause

The test/runtime code expects SolrJ class ZkClientClusterStateProvider, which is not available in the SolrJ version resolved on classpath (API moved/removed across Solr versions). This is a version compatibility break between test code and dependency set for this PR/job.

Solution

Update the ZK-based Solr client initialization to use the newer SolrJ API (CloudSolrClient.Builder) and avoid direct dependency on ZkClientClusterStateProvider.

Code suggestion (replace reflective/direct usage of ZkClientClusterStateProvider)

import org.apache.solr.client.solrj.impl.CloudSolrClient;

// old (fails when class removed):
// new ZkClientClusterStateProvider(zkHosts, zkChroot)

List<String> zkHosts = List.of(zkHostString); // e.g. "127.0.0.1:2181"
Optional<String> zkChroot = Optional.empty(); // or Optional.of("/solr") if used

CloudSolrClient solrClient = new CloudSolrClient.Builder(zkHosts, zkChroot)
        .build();
solrClient.setDefaultCollection(collection);

If your code currently creates a ClusterStateProvider explicitly, refactor to obtain it through CloudSolrClient rather than constructing ZkClientClusterStateProvider directly.


Dependency alignment fix (if needed)

In tika-integration-tests/tika-pipes-solr-integration-tests/pom.xml, ensure Solr test dependencies are version-aligned and explicit for the Solr 8 test path. If both Solr 8 and 9 tests coexist, isolate classpaths by profile or module so Solr 8 tests don’t run with Solr 9-only artifacts.

Example pattern:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.solr</groupId>
      <artifactId>solr-solrj</artifactId>
      <version>${solr8.version}</version>
    </dependency>
  </dependencies>
</dependencyManagement>

And for Solr8-specific tests, force that version in the module/profile running TikaPipesSolr8ZkTest.


Why this is the correct fix

The build fails only when running the Solr8 ZK test and errors at runtime on a missing SolrJ class. Replacing direct usage of that removed/relocated class with CloudSolrClient.Builder makes the code resilient across SolrJ versions and matches supported APIs.

==

PS about the other fail related to the timeout, that isn't related to your change. It may be because of a problem with gson.version. I remember that I reverted this once a few weeks ago to 2.13.2 because of that same problem, then forgot about it.

In SolrJ 10, ZkClientClusterStateProvider was moved from solr-solrj into a
separate solr-solrj-zookeeper module. Without it on the classpath, the ZK
code path in CloudSolrClient.Builder.build() throws ClassNotFoundException at
runtime. This was caught by TikaPipesSolr8ZkTest in CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI 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.

Pull request overview

This PR migrates Apache Tika’s Jetty dependency line from 11.x to Jetty 12.0.35 to address CVE-2026-2332 (HTTP/1.1 request smuggling), and updates dependent components (CXF and SolrJ) to compatible versions/modules.

Changes:

  • Upgrade Jetty to 12.0.35 (and rename Jetty HTTP/2 artifacts), plus upgrade CXF to 4.1.7.
  • Upgrade SolrJ to 10.0.0 and update Solr Pipes emitter/iterator and integration tests to SolrJ 10’s Jetty client classes/modules.
  • Update gRPC integration test to Jetty 12 resource handler API (setBaseResourceAsString).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tika-parent/pom.xml Bumps Jetty/CXF/SolrJ versions and updates Jetty HTTP/2 artifact coordinates; adjusts OSS Index exclusions.
tika-server/tika-server-core/pom.xml Switches to renamed Jetty HTTP/2 server artifact and adds jakarta.servlet-api dependency for Jetty 12.
tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitter.java Migrates Solr emitter from Http2 Solr client APIs to SolrJ 10 Jetty client APIs; adds proxy/basic auth wiring.
tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/iterator/solr/SolrPipesIterator.java Migrates Solr iterator to SolrJ 10 Jetty client APIs; updates LB client creation and proxy/basic auth wiring.
tika-pipes/tika-pipes-plugins/tika-pipes-solr/pom.xml Adds SolrJ 10 split modules (solr-solrj-jetty, solr-solrj-zookeeper).
tika-integration-tests/tika-pipes-solr-integration-tests/src/test/java/org/apache/tika/pipes/solr/tests/TikaPipesSolrTestBase.java Updates tests to use HttpJettySolrClient and updated SolrQuery import location.
tika-integration-tests/tika-pipes-solr-integration-tests/pom.xml Adds SolrJ 10 split modules for test scope.
tika-grpc/src/test/java/org/apache/tika/pipes/grpc/PipesBiDirectionalStreamingIntegrationTest.java Replaces removed Jetty 12 PathResource usage with ResourceHandler.setBaseResourceAsString().

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tika-server/tika-server-core/pom.xml
Comment thread tika-parent/pom.xml
- Move jakarta.servlet-api version management to tika-parent/pom.xml
  dependencyManagement; remove hardcoded 6.0.0 from tika-server-core
- Replace hardcoded 12.0.35 with \${jetty.http2.version} in OSS Index exclusion
- Validate auth scheme in SolrEmitter and SolrPipesIterator: throw
  TikaConfigException if a non-basic scheme is configured, since
  HttpJettySolrClient only supports basic auth
- Guard proxy configuration in both files: skip withProxyConfiguration()
  when port is null/zero to avoid silently misconfiguring the Jetty client

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Comment thread tika-parent/pom.xml Outdated
- Extract applyAuthAndProxy helper in SolrEmitter and SolrPipesIterator
  to eliminate duplicated auth-scheme validation and proxy-port guard
  across the ZK and LB client branches
- Update stale SolrJ version comment in tika-parent/pom.xml: replace
  "needs rework in a follow-up" with the actual current behaviour
  (basic auth and proxy wired; non-basic schemes rejected at startup)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

SolrEmitter and SolrPipesIterator both configure withRequestTimeout on
the ZooKeeper-based CloudSolrClient path but omitted it on the direct-URL
LBJettySolrClient path, allowing requests to hang indefinitely. Apply the
same HttpClientFactory request timeout consistently across both paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@THausherr THausherr requested a review from Copilot June 17, 2026 18:17

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Comment thread tika-server/tika-server-core/pom.xml
… ZK path

- Extract applyAuthAndProxy into SolrClientHelper to eliminate identical
  auth/proxy logic duplicated between SolrEmitter and SolrPipesIterator;
  helper reads proxy from HttpClientFactory directly (both callers already
  copy proxy config into the factory before building the Jetty client)
- Add missing withIdleTimeout to the ZK (CloudSolrClient) path in both
  classes so all three timeouts (request, connection, idle) are applied
  consistently across both ZK and LB paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants