A DESCRIPTION OF THE PROBLEM :
Code: https://github.com/openjdk/jdk/blob/8c0d026d0f508e0c896fd28d725915c52d1b689d/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java#L265
This line is throwing an exception when a response header is received from a server and the header name is invalid. Example of such a header:
$ curl -i -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' https://www.bi.go.id/en/statistik/informasi-kurs/transaksi-bi/Default.aspx
HTTP/1.1 200 OK
...
X-XSS-Protection : 1; mode=block
Note that there is a space before the : which makes the header name invalid.
The exception is thrown when using java.net.http.HttpClient to send a request.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile: javac Test.java
Run: java Test
We get the output:
Exception in thread "main" java.net.ProtocolException: Invalid header name "X-XSS-Protection "
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:907)
at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:133)
at Connect.main(Connect.java:19)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The invalid header is either discarded or an attempt is made to 'fix' it e.g. by trimming whitespace. It's true that the header name does not conform to the RFC, however, it would be good to not break potentially critical workflows because a rogue server somewhere sends an invalid header name.
ACTUAL -
An exception is thrown and the entire response is lost.
---------- BEGIN SOURCE ----------
// Test.java
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
public class Test. {
public static void main(String[] args) throws IOException, InterruptedException, NoSuchAlgorithmException, KeyManagementException {
var client = HttpClient.newBuilder().build();
var req = HttpRequest
.newBuilder()
.GET()
.uri(URI.create("https://www.bi.go.id/en/statistik/informasi-kurs/transaksi-bi/Default.aspx"))
.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")
.build();
client.send(req, HttpResponse.BodyHandlers.discarding());
}
}
---------- END SOURCE ----------
Code: https://github.com/openjdk/jdk/blob/8c0d026d0f508e0c896fd28d725915c52d1b689d/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java#L265
This line is throwing an exception when a response header is received from a server and the header name is invalid. Example of such a header:
$ curl -i -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' https://www.bi.go.id/en/statistik/informasi-kurs/transaksi-bi/Default.aspx
HTTP/1.1 200 OK
...
X-XSS-Protection : 1; mode=block
Note that there is a space before the : which makes the header name invalid.
The exception is thrown when using java.net.http.HttpClient to send a request.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile: javac Test.java
Run: java Test
We get the output:
Exception in thread "main" java.net.ProtocolException: Invalid header name "X-XSS-Protection "
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:907)
at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:133)
at Connect.main(Connect.java:19)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The invalid header is either discarded or an attempt is made to 'fix' it e.g. by trimming whitespace. It's true that the header name does not conform to the RFC, however, it would be good to not break potentially critical workflows because a rogue server somewhere sends an invalid header name.
ACTUAL -
An exception is thrown and the entire response is lost.
---------- BEGIN SOURCE ----------
// Test.java
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
public class Test. {
public static void main(String[] args) throws IOException, InterruptedException, NoSuchAlgorithmException, KeyManagementException {
var client = HttpClient.newBuilder().build();
var req = HttpRequest
.newBuilder()
.GET()
.uri(URI.create("https://www.bi.go.id/en/statistik/informasi-kurs/transaksi-bi/Default.aspx"))
.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")
.build();
client.send(req, HttpResponse.BodyHandlers.discarding());
}
}
---------- END SOURCE ----------