I've tried to get my Java Applet to read from my text file, but I do not have sufficient privaleges to read the file when i run the applet in my browser.
I have tried to use policy files but I cannot seem to get them to work.
I later tried
System.setProperty("java.security.policy", "*filelocation*");
but i got this error
java.security.AccessControlException: access denied (java.util.PropertyPermission java.security.policy write)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.System.setProperty(Unknown Source)
at BIT.init(BIT.java:35)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
What ways can I get my applet to run in my browser? It works fine in Eclipse's applet viewer.
The reason is specified within the What Applets Can and Cannot Do. It clearly specifies that:
Applets that are not signed are restricted to the security sandbox,
and run only if the user accepts the applet. Applets that are signed
by a certificate from a recognized certificate authority can either
run only in the sandbox, or can request permission to run outside the
sandbox. In either case, the user must accept the applet's security
certificate, otherwise the applet is blocked from running.
Later it states that:
Sandbox applets cannot perform the following operations:
They cannot access client resources such as the local filesystem, executable files, system clipboard, and printers.
They cannot connect to or retrieve resources from any third party server (any server other than the server it originated from).
They cannot load native libraries.
They cannot change the SecurityManager.
They cannot create a ClassLoader.
They cannot read certain system properties. See System Properties for a list of forbidden system properties.
To know about how to sign an Applet look here : How to Sign Applets Using RSA-Signed Certificates
You really ought to consider signing the applet.
This (short!) FAQ discusses both policies and signing:
http://www.coderanch.com/how-to/java/HowCanAnAppletReadFilesOnTheLocalFileSystem
Here is the offician documentation:
http://docs.oracle.com/javase/6/docs/technotes/guides/security/doprivileged.html
http://docs.oracle.com/javase/tutorial/deployment/applet/security.html
And here is a good (albeit old) tutorial:
http://faculty.kutztown.edu/spiegel/CSc421/SigningAnApplet.htm
Related
Hi all Java/Applet gurus,
I've stumbled upon an interesting problem with the latest JDK build (1.8.0_b26).
When running Sandbox Java Applet with the latest JDK, from within Java code we try to connect back to the server with a different protocol - instead of original HTTPS we use WSS (secured Websockets connection, we use third party Websockets Client Java library). As the result, JVM tries to retrieve crossdomain.xml file from the server. The problem is, that the file is retrieved using HTTP (and not HTTPS) protocol.
For example, in our case the server IP is 192.168.1.1, the applet is loaded over HTTPS default port (443). Using trace level 5 in Java console we see that the crossdomain.xml is retrieved from http://192.168.1.1:443. And of course it doesn't work because the server listens only for HTTPS connections on port 443 (and not HTTP).
On the other hand, when we use HTTP protocol and open new WS (unsecured Websockets connection) to the server, the problem doesn't appear, because crossdomain.xml is retrieved from http://192.168.1.1:80 and it is completely correct.
As the problem was further investigated, we've made few more observations:
It is possible to provide alternative location of crossdomain.xml file using jnlp.altCrossDomainXMLFiles Java VM parameter. We've never succeed to make this parameter work for us though (tried both in java_arguments list and as lone applet parameter). The possible reason might be that the parameter should be used only with Webstart application (although it is not written specifically in specs).
While establishing Websockets connection, the connection stack trace is as follows:
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:790) at
sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647) at
sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:787) at
sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647) at
sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1534)
at
sun.net.www.protocol.http.HttpURLConnection.access$200(HttpURLConnection.java:90)
at
sun.net.www.protocol.http.HttpURLConnection$9.run(HttpURLConnection.java:1431)
at
sun.net.www.protocol.http.HttpURLConnection$9.run(HttpURLConnection.java:1429)
at java.security.AccessController.doPrivileged(Native Method) at
java.security.AccessController.doPrivileged(AccessController.java:713)
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1428)
at com.sun.deploy.net.CrossDomainXML.check(Unknown Source) at
com.sun.deploy.net.CrossDomainXML.check(Unknown Source) at
sun.plugin2.applet.SecurityManagerHelper.checkConnectHelper(Unknown
Source) at
sun.plugin2.applet.AWTAppletSecurityManager.checkConnect(Unknown
Source) at
sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:624)
So we looked at the latest publicly available source code of CrossDomainXML.java class (back from 2010 though). And from the code it is evident, that http connection is always used while retrieving crossdomain.xml file from server, regardless what is the original browser connection.
So the questions are:
Might it be a JDK bug or the strict usage of HTTP for crossdomain.xml is by design?
Is jnlp.altCrossDomainXMLFiles JVM parameter supported inside Sandbox applet?
Is there a way access the latest version of com.sun.deploy.net.CrossDomainXML.java source code to get a full picture of what is going on?
Thank you very much in advance.
Best regards,
Mark
in order to get rid of the http://myhost/crossdomain.xml request, there is nothing you can do except adding something like this into your java.policy file:
permission java.net.SocketPermission "myhost:1024-", "connect, resolve";
You can restrict that to a specific certificate signer in order to enforce this policy, see https://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html#SocketPermission
We use it like this in an applet early in the init-process (applet constructor) and it works:
try
{
System.setProperty("jnlp.altCrossDomainXMLFiles", //
"http://www.some-domain.de/crossdomain.xml" //
+ ",https://www.secure-domain.de:8443/crossdomain.xml" //
);
}
catch (Exception e)
{
e.printStackTrace();
}
I have a self signed applet, which was running fine till jre 7u21 came around.
Now I get the following AccessControlException when calling java.net.ProxySelector.setDefault:
Caused by: java.security.AccessControlException: access denied
("java.net.NetPermission" "setProxySelector")
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at sun.plugin2.applet.FXAppletSecurityManager.checkPermission(Unknown Source)
at java.net.ProxySelector.setDefault(Unknown Source)
For testing I tried removing this call, but other AccessControlExceptions start popping up. Apparently 7u21 applied significant changes to the applet's security model.
I always assumed that if the user accepts an applet's digital signature, no security restrictions apply. 7u21 now says that even signed applets can run in sandbox mode without clearly specifying when this is the case. (7u21 release notes). My security level slider in the Java control panel is set to medium (lowest level). Any recommendations how to resolve this?
Update: I resolved it by adding the security tag
<security>
<all-permissions/>
</security>
to the applet's jnlp file (applet is deployed via dtjava). It is now running under 7u21 without problems.
I am trying to execute this jnlp application.
However, I keep receiving this security exception:
java.lang.ExceptionInInitializerError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:399)
at java.lang.Class.newInstance0(Class.java:370)
at java.lang.Class.newInstance(Class.java:322)
at com.sun.javafx.applet.FXApplet2.init(FXApplet2.java:63)
at com.sun.deploy.uitoolkit.impl.fx.FXApplet2Adapter.init(FXApplet2Adapter.java:207)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.net.useSystemProxies" "write")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:364)
at java.security.AccessController.checkPermission(AccessController.java:560)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.System.setProperty(System.java:783)
at ensemble.Ensemble2.<clinit>(Ensemble2.java:77)
... 10 more
I tried changing the security settings in the Java control panel (OSX 10.8.3), but they seem to be disabled and I cannot modify them (I do can check the "Enable Java content in the browser" option, but it is resetted when I click apply). This is shown in the following figure:
Is there another mechanism for bypassing the Java security manager and being able to execute a jnlp application ?
UPDATE:
After reinstalling Java I was finally able to change the security options in the Java Control panel (I did not do anything special, just reinstall it from scratch). Unfortunately, when I execute the jnlp application it dies silently without showing any errors. This problem could be related to the fact that I am using the jdk 1.8 (since the jnlp application requires javafx) and it is just a preview version (and OSX does not seem to like a lot Java these days...), it is my best guess but I cannot be completely sure.
Possible reasons for this:
I have heard that Java 7 on Mac is still not stable.
By default JNLP files run in a "sandbox" to prevent malicious code from wreaking havoc on your system. This sandbox restricts access to the local filesystem and local network. I imagine that system properties are restricted too, and it looks like the app is trying to write to them. To allow unrestricted access, you need to sign the JAR file and configure the JNLP file with <security><all-permissions/></security>
We're developing an applet and need it to be able to read/write files in the user's temporary files directory (e.g. C:\Documents and Settings\USERNAME\Local Settings\Temp).
The applet is signed, the user clicks the 'allow' option on applet startup, and the Java Control Panel has "Allow user to grant permissions to signed content" and "Allow user to grant permissions to content from an untrusted authority" enabled.
However, on startup, we get a SecurityException:
java.lang.SecurityException: Unable to create temporary file
at java.io.File.checkAndCreate(Unknown Source)
at java.io.File.createTempFile(Unknown Source)
at java.io.File.createTempFile(Unknown Source)
at com.jniwrapper.util.AppletHelper.b(SourceFile:104)
at com.jniwrapper.util.AppletHelper.a(SourceFile:79)
at com.jniwrapper.util.AppletHelper.b(SourceFile:50)
at com.jniwrapper.util.AppletHelper.init(SourceFile:122)
at com.x.Y.init(Y.java:31)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Exception: java.lang.SecurityException: Unable to create temporary file
If we edit the java.policy file to grant all to everything then the applet works OK but this is clearly insecure. What minimal permissions must we grant to allow the applet to read/write/create files in the user's temporary files directory?
Using the policy file is kinda ok for testing but you should not be relying on it for your finished code, especially when granting a file permission, it is dangerous.
To interact with files you need to do the following.
Sign your jar - tons of tutorials like this, you can just do a self signed one.
Add the file creation code to a privileged block here is an example
File myFile = (File) AccessController.doPrivileged(new PrivilegedAction() {
public Object run()
{
return new File("C:\\MyFolder\\MyFile");
}
});
Got to that same point. To grant the permission as close as possible to what is needed minimally, you can grant a FilePermission on ${java.io.tmpdir}\- with actions read,write,delete. This worked for me.
Of course you have to replace the ${...} by the value of the system property java.io.tmpdir. This property is used by java.io.File.createTempFile.
Note: With someDir\- you grant recursive access to all subdirs of the someDir path. At this point you can use someDir\* but I haven't tested it.
If you use policy files to grant permissions there is a good chance that those files already support referencing system properties. But google that again to be sure. If you use a custom policy implementation you can easily create the permission java.io.FilePermission.
I've got a signed java applet (using a self-signed-certificate) which has to access the user's file system. I have to do it, so please no replies ala "you shouldn't do it" :)
The thing is, when I execute the Applet from Firefox 3.0 / Mac, everything works as desired, I get all access just as it should.
When I use Safar 4 / Mac, I don't get access. The line I especially have problems with is System.getProperty() (although when I stub that out, the FS access doesn't work either)
String home = System.getProperty("user.home");
The Exception I get is the following:
java.security.AccessControlException: access denied (java.util.PropertyPermission user.home read)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
at java.security.AccessController.checkPermission(AccessController.java:427)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1285)
at java.lang.System.getProperty(System.java:628)
at de.samedi.searcher.Searcher.<init>(Searcher.java:49)
at de.samedi.searcher.Applet.getSearcher(Applet.java:193)
at de.samedi.searcher.Applet.getSearcher(Applet.java:187)
at de.samedi.searcher.Applet.addPatient(Applet.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at sun.plugin.javascript.invoke.JSInvoke.invoke(JSInvoke.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at sun.plugin.javascript.JSClassLoader.invoke(JSClassLoader.java:44)
at sun.plugin.liveconnect.PrivilegedCallMethodAction.run(SecureInvocation.java:658)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.liveconnect.SecureInvocation$2.run(SecureInvocation.java:214)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.liveconnect.SecureInvocation.CallMethod(SecureInvocation.java:192)
at sun.plugin.liveconnect.SecureInvocation.access$300(SecureInvocation.java:52)
at sun.plugin.liveconnect.SecureInvocation$CallMethodThread.run(SecureInvocation.java:123)
As I said, this works perfectly on Firefox. Gotta check Windows Browser today...
Any Ideas?
Once you have your jar compiled and signed you should run the -verify option to ensure its signed properly.
If the verification is ok look at the installed certificates on your browsers.
I haven't done anything in Safari only IE, but I imagine there is a place similar to I.E. where you can at least view the installed certificates. I would verify the certificate is installed.
Also make sure your code is running in a privileged block.
String home = System.getProperty("user.home");
will always throw an error in 1.4 or higher. Unless you have edited the java.policy file for All Permissions
Try using this in combination with your signed jar.
String home = (String) AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
return System.getProperty("user.home");
}
});
Has the user accepted full access for your applet in Safari? Sounds like the security manager kicking in.
I remember having a similar problem in an older version of Safari (this was years ago), and the solution I found was adding a delay to the applet. It seemed Safari for some reason was allowing the applet to run before the user was given the "trust this applet" dialogue (other browsers would not start the applet until after the user granted or denied access). At that point the applet was not trusted and a security exception would occur. Even though the user would then allow trust, it was too late as the applet had already run and failed. I had to add a delay for safari, so it would not try doing anything that needed secure access until a period of time had passed, allowing the user to give access before the applet tried doing anything needing security access.