From ce7e28f3e6e44f6558968cb731d6fb5a90f29d9d Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 12 May 2009 16:32:34 +0100 Subject: [PATCH] 6801071: Remote sites can compromise user privacy and possibly hijack web sessions Reviewed-by: jccollet, hawtin --- jdk/make/sun/net/FILES_java.gmk | 1 + jdk/src/share/classes/java/net/Socket.java | 2 +- .../classes/java/net/SocksSocketImpl.java | 25 ++++++++--- jdk/src/share/classes/java/net/URL.java | 2 +- .../classes/sun/net/ApplicationProxy.java | 43 +++++++++++++++++++ .../www/protocol/http/HttpURLConnection.java | 18 +++++--- 6 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 jdk/src/share/classes/sun/net/ApplicationProxy.java diff --git a/jdk/make/sun/net/FILES_java.gmk b/jdk/make/sun/net/FILES_java.gmk index 1ab771a37f1..00b6223b8da 100644 --- a/jdk/make/sun/net/FILES_java.gmk +++ b/jdk/make/sun/net/FILES_java.gmk @@ -24,6 +24,7 @@ # FILES_java = \ + sun/net/ApplicationProxy.java \ sun/net/InetAddressCachePolicy.java \ sun/net/URLCanonicalizer.java \ sun/net/NetworkClient.java \ diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java index 110a6a5f1a9..39dfebd4180 100644 --- a/jdk/src/share/classes/java/net/Socket.java +++ b/jdk/src/share/classes/java/net/Socket.java @@ -118,7 +118,7 @@ class Socket implements java.io.Closeable { if (proxy == null) { throw new IllegalArgumentException("Invalid Proxy"); } - Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy); if (p.type() == Proxy.Type.SOCKS) { SecurityManager security = System.getSecurityManager(); InetSocketAddress epoint = (InetSocketAddress) p.address(); diff --git a/jdk/src/share/classes/java/net/SocksSocketImpl.java b/jdk/src/share/classes/java/net/SocksSocketImpl.java index e73b6c9467e..4561b6e1e56 100644 --- a/jdk/src/share/classes/java/net/SocksSocketImpl.java +++ b/jdk/src/share/classes/java/net/SocksSocketImpl.java @@ -47,6 +47,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { private Socket cmdsock = null; private InputStream cmdIn = null; private OutputStream cmdOut = null; + /* true if the Proxy has been set programatically */ + private boolean applicationSetProxy; /* false */ + SocksSocketImpl() { // Nothing needed @@ -64,6 +67,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { // Use getHostString() to avoid reverse lookups server = ad.getHostString(); port = ad.getPort(); + applicationSetProxy = true; } } @@ -165,8 +169,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { throw (IOException) pae.getException(); } } else { - userName = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("user.name")); + userName = getUserName(); } } if (userName == null) @@ -267,8 +270,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { out.write((endpoint.getPort() >> 8) & 0xff); out.write((endpoint.getPort() >> 0) & 0xff); out.write(endpoint.getAddress().getAddress()); - String userName = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("user.name")); + String userName = getUserName(); try { out.write(userName.getBytes("ISO-8859-1")); } catch (java.io.UnsupportedEncodingException uee) { @@ -588,8 +590,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { out.write((super.getLocalPort() >> 8) & 0xff); out.write((super.getLocalPort() >> 0) & 0xff); out.write(addr1); - String userName = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("user.name")); + String userName = getUserName(); try { out.write(userName.getBytes("ISO-8859-1")); } catch (java.io.UnsupportedEncodingException uee) { @@ -1052,4 +1053,16 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { super.close(); } + private String getUserName() { + String userName = ""; + if (applicationSetProxy) { + try { + userName = System.getProperty("user.name"); + } catch (SecurityException se) { /* swallow Exception */ } + } else { + userName = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("user.name")); + } + return userName; + } } diff --git a/jdk/src/share/classes/java/net/URL.java b/jdk/src/share/classes/java/net/URL.java index 73818e960d8..33cfe039654 100644 --- a/jdk/src/share/classes/java/net/URL.java +++ b/jdk/src/share/classes/java/net/URL.java @@ -1005,7 +1005,7 @@ public final class URL implements java.io.Serializable { } // Create a copy of Proxy as a security measure - Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy); SecurityManager sm = System.getSecurityManager(); if (p.type() != Proxy.Type.DIRECT && sm != null) { InetSocketAddress epoint = (InetSocketAddress) p.address(); diff --git a/jdk/src/share/classes/sun/net/ApplicationProxy.java b/jdk/src/share/classes/sun/net/ApplicationProxy.java new file mode 100644 index 00000000000..2c84e3649e3 --- /dev/null +++ b/jdk/src/share/classes/sun/net/ApplicationProxy.java @@ -0,0 +1,43 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.net; + +import java.net.Proxy; +import java.net.SocketAddress; + +/** + * Proxy wrapper class so that we can determine application set + * proxies by type. + */ +public final class ApplicationProxy extends Proxy { + private ApplicationProxy(Proxy proxy) { + super(proxy.type(), proxy.address()); + } + + public static ApplicationProxy create(Proxy proxy) { + return new ApplicationProxy(proxy); + } +} diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 6f3250b30eb..9f5d7303abc 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -575,12 +575,20 @@ public class HttpURLConnection extends java.net.HttpURLConnection { responses = new MessageHeader(); this.handler = handler; instProxy = p; - cookieHandler = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + if (instProxy instanceof sun.net.ApplicationProxy) { + /* Application set Proxies should not have access to cookies + * in a secure environment unless explicitly allowed. */ + try { + cookieHandler = CookieHandler.getDefault(); + } catch (SecurityException se) { /* swallow exception */ } + } else { + cookieHandler = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { public CookieHandler run() { - return CookieHandler.getDefault(); - } - }); + return CookieHandler.getDefault(); + } + }); + } cacheHandler = java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public ResponseCache run() {