Skip to content

Istio breaks java.net.http.HttpClient introduced as incubating in Java 9 and stable in Java 11 #16391

@rdsubhas

Description

@rdsubhas

A fully reproduceable test case with ready kubectl apply yamls, steps, source code and screenshots are here: https://github.com/rdsubhas/java-istio

Bug description

Java 11+ core HttpClient optionally supports HTTP/2, and as per official HTTP/2 spec rfc7540, it sends optional Upgrade: h2c header, which is purely indicative and can/should be ignored and treated as any other X- header if the target doesn't support HTTP/2. The HTTP/2 spec shows clearly on how the header can be ignored and normal HTTP/1.1 response can be returned.

In Istio, even though we explicitly name the port as http (and NOT http2), and the http/2 spec explicitly states these headers as optional, it treats these optional headers as mandatory, and returns a confusing HTTP 403 Forbidden.

This is not an exotic use case. This basically breaks all Java 11 applications and beyond, and most Java 9 applications that use spring-boot, the de-facto java web framework, since spring-boot uses the exact same HTTP/2 functionality under the hoods from Java 9 onwards.

It may break other libraries in other languages/platforms which normally implement the HTTP/2 spec to send these optional headers. It has been easily reproduced with curl --http2. I can submit test cases for most other language libraries.

Why is this called "all java 11+ and partially 9+applications"? Because it breaks the core language sdk, and all applications who are making a http call are impacted. Those who don't, don't know they're impacted and just sitting on somewhere in the dependency tree (like an oauth client or something) to break. Not withstanding all language libraries and servers that implement http/2 spec as per the optional headers.

Affected product area (please put an X in all that apply)

[ ] Configuration Infrastructure
[ ] Docs
[ ] Installation
[x] Networking
[ ] Performance and Scalability
[ ] Policies and Telemetry
[ ] Security
[ ] Test and Release
[x] User Experience
[ ] Developer Infrastructure

Expected behavior

A port named as http must work as HTTP on an incoming istio sidecar.

Any other optional, ignoreable HTTP/2 headers should not break a http port and return a403 on a cluster with no restrictions or policies (ALLOW_ANY traffic mode, mTLS permissive, no policies or rules, no other istio resources).

Steps to reproduce the bug

A fully reproduceable test case with ready kubectl apply yamls are here: https://github.com/rdsubhas/java-istio

Version (include the output of istioctl version --remote and kubectl version)

  • Istio 1.1.7-gke.0
  • Kubernetes v1.13.7-gke.8
  • mTLS disabled, ALLOW_ANY mode. No custom rules whatsoever.

How was Istio installed?

  • GKE Istio checkbox
  • mTLS disabled, ALLOW_ANY mode. No custom rules whatsoever.

Environment where bug was observed (cloud vendor, OS, etc)

  • Google Kubernetes Engine

Paste a funny image

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions