Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2138082 | 5.0u8 | Nishant Patel | P2 | Resolved | Fixed | b02 |
JDK-2138131 | 1.4.2_13 | Nishant Patel | P2 | Resolved | Fixed | b01 |
FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
When making an HTTP(S) request that tunnels through an HTTP proxy (using the CONNECT method) any headers set on the HttpURLConnection are sent to the proxy server as well as to the destination host (through the tunnel). This can cause sensitive data (e.g. Authorization headers) to travel across the network plain-text, even though the program believes it is connecting to the server using HTTPS.
The problem I am describing is not an issue with base64 encoding the
username:password pair in the Authorization header. Our code takes care
of it and properly authenticates with the end server. The problem I am
seeing is more general.
The expectation is that when making a connection to an HTTPS URL, both
the request headers and the request body will be sent to the server
protected by SSL/TLS encryption as negotiated in the SSL handshake.
If the connection is made through a proxy server, Java makes a CONNECT
request to open a channel to the destination server. In this case, any
request headers set with setRequestProperty are sent to the proxy server
even though the programmers intent is to send these headers to the final
destination server. This can result in exposing sensitive information
unencrypted on the network.
The behavior can be examined using a packet analyzer and the test code I
provided with the original bug report. The expectation is that the
X-Test-Header is only sent to the destination server once the SSL
handshake has been completed through the tunneled connection established
by the HTTP CONNECT request.
Note that in order to see the behavior I describe the destination URL
must be an HTTPS URL.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the included program giving the name and port number of a proxy server as the first two arguments and the url of the destination server as the third argument. Use a packet analyzer to view the packets sent by the program.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The X-TestHeader should not be sent to the proxy server.
ACTUAL -
The X-TestHeader was sent to the proxy server.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.net.*;
import java.io.*;
public class ProxyBad {
public static void main(String args[]) throws Exception {
System.setProperty("https.proxyHost", args[0]);
System.setProperty("https.proxyPort", args[1]);
URL u = new URL(args[2]);
URLConnection c = u.openConnection();
/* I want this header to go to the destination server only, protected
* by SSL; but it gets sent to the proxy as well in plaintext. */
c.setRequestProperty("X-TestHeader", "value");
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
System.out.println(br.readLine());
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
If possible, clear the https proxy properties or set the http noproxy property before making the connection so that a proxy will not be used. This, of course, will not work if it is actually necessary to use a proxy server.
###@###.### 2005-2-08 13:12:51 GMT
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
When making an HTTP(S) request that tunnels through an HTTP proxy (using the CONNECT method) any headers set on the HttpURLConnection are sent to the proxy server as well as to the destination host (through the tunnel). This can cause sensitive data (e.g. Authorization headers) to travel across the network plain-text, even though the program believes it is connecting to the server using HTTPS.
The problem I am describing is not an issue with base64 encoding the
username:password pair in the Authorization header. Our code takes care
of it and properly authenticates with the end server. The problem I am
seeing is more general.
The expectation is that when making a connection to an HTTPS URL, both
the request headers and the request body will be sent to the server
protected by SSL/TLS encryption as negotiated in the SSL handshake.
If the connection is made through a proxy server, Java makes a CONNECT
request to open a channel to the destination server. In this case, any
request headers set with setRequestProperty are sent to the proxy server
even though the programmers intent is to send these headers to the final
destination server. This can result in exposing sensitive information
unencrypted on the network.
The behavior can be examined using a packet analyzer and the test code I
provided with the original bug report. The expectation is that the
X-Test-Header is only sent to the destination server once the SSL
handshake has been completed through the tunneled connection established
by the HTTP CONNECT request.
Note that in order to see the behavior I describe the destination URL
must be an HTTPS URL.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the included program giving the name and port number of a proxy server as the first two arguments and the url of the destination server as the third argument. Use a packet analyzer to view the packets sent by the program.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The X-TestHeader should not be sent to the proxy server.
ACTUAL -
The X-TestHeader was sent to the proxy server.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.net.*;
import java.io.*;
public class ProxyBad {
public static void main(String args[]) throws Exception {
System.setProperty("https.proxyHost", args[0]);
System.setProperty("https.proxyPort", args[1]);
URL u = new URL(args[2]);
URLConnection c = u.openConnection();
/* I want this header to go to the destination server only, protected
* by SSL; but it gets sent to the proxy as well in plaintext. */
c.setRequestProperty("X-TestHeader", "value");
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
System.out.println(br.readLine());
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
If possible, clear the https proxy properties or set the http noproxy property before making the connection so that a proxy will not be used. This, of course, will not work if it is actually necessary to use a proxy server.
###@###.### 2005-2-08 13:12:51 GMT
- backported by
-
JDK-2138082 HTTP tunnel connections send user headers to proxy
- Resolved
-
JDK-2138131 HTTP tunnel connections send user headers to proxy
- Resolved
- duplicates
-
JDK-6424844 security problem
- Closed
-
JDK-6358816 java.io.IOException thrown after accept "Hostname Mismatch" warning
- Closed
-
JDK-6206466 Plugin can't make SSL connections through squid proxy with NTLM authentication
- Closed
-
JDK-6356776 Incorrect http1.1 CONNECT message
- Closed
- relates to
-
JDK-6216082 Redirect problem with HttpsURLConnection using a proxy
- Resolved
(1 duplicates, 1 relates to)