How the Applet Network Security Policy works

Since this is a source of endless confusion, here is an overview of how things work when using java.net.Socket or java.net.URLConnection (note that java.applet.AppletContext.showDocument() is not subject to any security restrictions and hence the discussion here does not apply to it). What follows is true for Netscape version 2.01 or later and JDK 1.0.2 or later.

Status Quo

Applications

Applications can connect anywhere they like, unless you install your own security manager which limits connections. Therefore for the rest of the article we will only talk about applets running in a browser or via the Appletviewer.

Applets

Applets are divided into two categories: trusted and untrused. Trusted applets are not subject to any security restrictions and can therefore open connections to any host at will; untrusted applets are subject to the security restrictions described below.

When an applet is loaded a check is first made to see if an applet by that name (the value of the CODE attribute in the APPLET tag) exists in the classpath (if none was explicitly set, then just the internal default classpath is used); if so, the applet found in the classpath is loaded. Applets loaded this way are considered trusted. If no applet by the requested name is found in the classpath then it is loaded from the location specified by the combination of urls used to load the page containing the applet and in the CODEBASE attribute. Applets loaded this way are considered untrusted.

Since trusted applets have no security restrictions imposed on them they will also be ignored for the rest of this document. From now on all applets are assumed to be untrusted. Furthermore, since where an applet was loaded from plays a central role in determining which host(s) it can connect to, the host that served the applet will be referred to in the following as the originating host.

Here now are the security restrictions imposed on untrusted applets.

Appletviewer (JDK)

The default security mode is to only allow connections to the originating host. This behaviour can be modified however using either the Applet->Properties Menu or by setting the property appletviewer.security.mode=xxx in ~/.hotjava/properties directly, where xxx is one of unrestricted for unrestricted access, host for the default behaviour, or none to dissallow all network connections. Note: the above Menu item actually sets this property for you.

Netscape

The security restrictions here are similar to those for the default mode of Appletviewer. The exception is that for java.net.URLConnection the protocol must also match; so e.g. if you load an applet via the https protocol from a secure server, then you can only use https: urls for the URLConnection. Also one further thing to note is when an applet was loaded via the file protocol (or via the 'Open File...' menu) netscape seems to forget this, and will throw a security exception 'security.protocol' even if you try to open a file: url.

There is no supported way for changing the network security policy; for an unsupported way check out How to bypass Netscape's SecurityManager, but be warned that I take no responsibility whatsoever for any consequences arising from following the instructions therein.

HotJava

I haven't played around with HotJava so I'm unsure of the exact implementation there. However I do believe it has the same or similar properties and behaviour as as the Appletviewer. If you have any details, or can confirm or invalidate my statement, please contact me.

Microsoft Internet Explorer

Again, I haven't played with the MSIE (as I only work on U*IX machines) so I'm not sure the of details, but I'd guess the behaviour is similar to that of Netscape. If you have any further info please contact me.

Some Implications of the "can connect to originating host only" Policy

Implications for Proxies

If you are behind a firewall and use a proxy server to get out then you are basically prevented from using java.net.Socket for connections. The problem is this: support for proxies is part of the protocol that you are using above TCP/IP (such as HTTP, FTP, Gopher, etc); it's therefore not possible to encapsulate the proxy specific stuff at the socket layer (as opposed to e.g. socks). So if you now open a connection using java.net.Socket, who are you going to consider as the host you're allowed to connect to? If you take the proxy server then that enables you to connect to any machine you'd like (via the proxy server) thereby circumventing the whole security policy. If you say no, I want to consider the true originating host (the one that the proxy server eventually connected to) then you're effectively forbidden from doing any network connection at all, since connecting to the proxy would be connecting to a different host than the one the applet was loaded from. The latter stance is what Netscape and the Appletviewer take, making it impossible for people behind firewalls to run applets which try to connect to hosts outside the firewall via java.net.Socket. Also, it's worth mentioning that most firewalls do not allow TCP connections out, that is the only way out is via the proxy servers (usually for http and ftp, and possibly Gopher). So even if the security manager allowed connections to the firewall chances are you wouldn't get out.

Things are slightly better if you use the java.net.URLConnection class. Here the implementation can (and does) shield the fact that a proxy is being used, checking the true destination of the request against the applets origin, and allowing such connections via the proxy (plus you know that http connections are allowed through the firewall, since that's the way the applet got loaded in the first place). Currently therefore, if you are running Netscape or Appletviewer, using URLConnection will work even if you are behind a firewall and use an http proxy to get out.

As an aside, some (many?) firewalls do not provide DNS host name resolution for names of hosts outside the firewall, which means that trying to connect to "host.name.org" from inside the firewall will fail (you get a security exception like

"Security Exception: socket.connect:xxx.yyy.zzz->xxx.yyy.zzz"
- note the same host name on each side of the arrow). What is happending is that Netscape's applet security manager tries to translate host names to IP-addresses and then compares these IP-addresses (this is to prevent DNS spoofing). However since the names cannot be translated due to the firewall setup an UnknownHost exception is thrown, which in turn is turned into the above security exception. The workaround is to load the page containing the applet using an IP-address instead of a host name in the url (e.g. "http://123.42.18.19/java/CoolApp.html") - getCodeBase().getHost() and the internal server name will then both return the IP-address (i.e. "123.42.18.19"), which in turn is "translated" to the same IP-address. The only drawback is that this won't work on MSIE (it seems to require that you use host names, and will puke with a '"ClassFile" not found' if you use IP-addresses). Alternatively, with Netscape 4.0 or later you can set a security preference which tells Netscape to not try and lookup the IP-address, but instead to trust the proxy; see the trustProxy preference.

Note: To enable the proxy under JDK 1.0.2 you need to set the property proxySet to true, set the proxyHost property to point to the proxy server, and set the proxyPort property to the correct port. In the Appletviewer these can also be set using the Applet -> Properties menu. For JDK 1.1 you must set http.proxyHost to the correct host and http.proxyPort to the correct port; setting http.proxyHost to null disables the proxy.

Implications for SOCKS

Currently under Netscape the situation is the same here as for proxies. However with the way SOCKS works it is possible to put SOCKS support in the java.net.Socket code (well, actually the SocketImpl code), resulting in an encapsulation of the SOCKS protocol layer and allowing the enforcement of the security policy without undue negative impact on people behind firewalls. This has been done for the JDK 1.0.2, but unfortunately not in Netscape (however the semi-official statement from them is that this is considered a bug, and we can therefore expect this to be fixed sometime - just don't ask when!). So if you've got a SOCKS server then everything is fine as long as you use the Appletviewer or java.net.URLConnection, but using java.net.Socket under Netscape will give you a SecurityException.

If you're working on OS/2 (at least Warp 4) then it is worth noting that on this system the basic TCP/IP stack already contains support for SOCKS. Therefore on this system you can use java.net.Socket under Netscape even if you are behind a SOCKS proxy (thanx to Mark James for this info).

While on the subject, the SOCKS support in the JDK is enabled by setting the socksProxyHost property to point to the socks server; if the SOCKS server is not listening on the default socks port (1080) then you must also set the socksProxyPort property to the correct port. In the Appletviewer these can also be set using the Applet -> Properties menu.

HTTPClient

Since the HTTPClient uses java.net.Socket for connections, the security restrictions and setup when using HTTPClient are the same as described above for java.net.Socket.

Summary

This table summarizes where you are allowed to connect to when using java.net.Socket:

Appletviewer

Netscape

No Proxy

Depending on the setting of the appletviewer.security.mode property, you can connect nowhere, only to the originating host, or anywhere.

Can only connect to the originating host.

SOCKS Proxy

Same as no proxy, assuming you set the socksProxyHost property.

No connections allowed
(except under OS/2, where it's the same as with no proxy).

HTTP Proxy

if the appletviewer.security.mode property is set to none then all connections are allowed; else no connections are allowed.

No connections allowed.

This table summarizes where you are allowed to connect to when using java.net.URLConnection:

Appletviewer

Netscape

No Proxy

Depending on the setting of the appletviewer.security.mode property, you can connect nowhere, only to the originating host, or anywhere.

Can only connect to the originating host.

SOCKS Proxy

Same as no proxy, assuming you set the socksProxyHost property.

Same as no proxy, assuming Netscape has been properly configured to use the proxy (Options -> Network Preferences... -> Proxy).

HTTP Proxy

Same as no proxy, assuming you set the appropriate properties (see Proxies).

Same as SOCKS Proxy.

Further Reading

* Sun's Security FAQ
* The Java Tutorial - Security Restrictions
* SOCKS Home Page

[HTTPClient]


Ronald Tschalär / 13 Jan 1998 / ronald@innovation.ch.