# Applet Signiert und trotzdem Fehlermeldung



## unityself (29. Jan 2012)

Ich hab ein Applet Signiert und bekomme trotzdem jetzt eine Fehlermeldung:
[WR]
Java.lang.reflect.InvocationTargetException
	at com.sun.deploy.util.DeployAWTUtil.invokeAndWait(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager.runOnEDT(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.RuntimeException: java.lang.InstantiationException: com.aranai.crafty.Crafty
	at sun.plugin2.applet.Plugin2Manager$12.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.InstantiationException: com.aranai.crafty.Crafty
	at java.lang.Class.newInstance0(Unknown Source)
	at java.lang.Class.newInstance(Unknown Source)
	... 15 more
Ausnahme: java.lang.reflect.InvocationTargetException[/WR]


----------



## L-ectron-X (29. Jan 2012)

API Doc hat gesagt.:
			
		

> InvocationTargetException is a checked exception that wraps an exception thrown by an invoked method or constructor.



OK, hast du noch weitere Informationen zum Problem? 
Wie sieht dein applet-Tag aus? Externe Bibliotheken eingebunden etc?


----------



## AmunRa (29. Jan 2012)

Weil die Exception nichts mit einem signierten Applet zu tun hat


----------



## unityself (29. Jan 2012)

Es befinden sich zwei komische dateien in der jar datei beide mit xml code.

.project
[XML]<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>Crafty</name>
	<comment></comment>
	<projects>
	</projects>
	<buildSpec>
		<buildCommand>
			<name>org.eclipse.jdt.core.javabuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
	</buildSpec>
	<natures>
		<nature>org.eclipse.jdt.core.javanature</nature>
	</natures>
	<filteredResources>
		<filter>
			<id>1296900991353</id>
			<name></name>
			<type>6</type>
			<matcher>
				<id>org.eclipse.ui.ide.orFilterMatcher</id>
				<arguments>
					<matcher>
						<id>org.eclipse.ui.ide.multiFilter</id>
						<arguments>1.0-name-matches-false-false-*.log*</arguments>
					</matcher>
					<matcher>
						<id>org.eclipse.ui.ide.multiFilter</id>
						<arguments>1.0-name-matches-false-false-*.txt</arguments>
					</matcher>
					<matcher>
						<id>org.eclipse.ui.ide.multiFilter</id>
						<arguments>1.0-name-matches-false-false-*.properties</arguments>
					</matcher>
					<matcher>
						<id>org.eclipse.ui.ide.multiFilter</id>
						<arguments>1.0-name-matches-false-false-*.psd</arguments>
					</matcher>
				</arguments>
			</matcher>
		</filter>
		<filter>
			<id>1296900991355</id>
			<name></name>
			<type>10</type>
			<matcher>
				<id>org.eclipse.ui.ide.orFilterMatcher</id>
				<arguments>
					<matcher>
						<id>org.eclipse.ui.ide.multiFilter</id>
						<arguments>1.0-name-matches-false-false-plugins</arguments>
					</matcher>
					<matcher>
						<id>org.eclipse.ui.ide.multiFilter</id>
						<arguments>1.0-name-matches-false-false-world</arguments>
					</matcher>
				</arguments>
			</matcher>
		</filter>
	</filteredResources>
</projectDescription>
[/XML]

und
Crafty.jardesc
[XML]<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
<jardesc>
    <jar path="D:/Games/MineCraft/CraftBukkit/crafty.jar"/>
    <options buildIfNeeded="true" compress="true" descriptionLocation="/Crafty/Crafty.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
    <selectedProjects/>
    <manifest generateManifest="false" manifestLocation="/Crafty/src/Manifest.txt" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
        <sealing sealJar="false">
            <packagesToSeal/>
            <packagesToUnSeal/>
        </sealing>
    </manifest>
    <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
        <file path="/Crafty/.classpath"/>
        <file path="/Crafty/.project"/>
        <javaElement handleIdentifier="=Crafty/src"/>
    </selectedElements>
</jardesc>[/XML]

Der Mainfest eintrag:

Manifest-Version: 1.0
Main-Class: com.aranai.crafty.Crafty
Class-Path: craftbukkit.jar

Der Datei Name:

crafty.jar

Applet einbindung html code


```
<applet archive="crafty.jar" code="com/aranai/crafty/Crafty.class" width="800" height="600">
</applet>
```


----------



## L-ectron-X (29. Jan 2012)

Im Manifest gibts einen Hinweis auf eine main-class? Dann ist das eventuell eine Hybrid-Anwendung.

Versuche mal folgenden Applet-Tag:

```
<applet archive="crafty.jar" code="com.aranai.crafty.Crafty.class" width="800" height="600">
</applet>
```


----------



## unityself (29. Jan 2012)

leider funktionniert auch das nicht:autsch:


----------



## L-ectron-X (29. Jan 2012)

> [XML]<jar path="D:/Games/MineCraft/CraftBukkit/crafty.jar"/>[/XML]


Das geht garantiert schief.

Vielleicht hast du da gar kein Applet, sondern eine Applikation.
Im Manifest gibts einen Hinweis auf eine Main-Class...

Versuche aber mal noch folgendes Applet-Tag:

```
<applet archive="crafty.jar,craftbukkit.jar" code="com.aranai.crafty.Crafty.class" width="800" height="600">
</applet>
```

Gib dann ggf. noch mal die aktuelle Fehlermeldung.


----------



## unityself (29. Jan 2012)

jetzt kommt gar nichts

Ach vergiss es!


----------



## Marcel Lübeck (28. Jul 2012)

So wie ich aus den Foren entnehme, sollte man eine lokale Datei mit einem Java-Applet lesen können, wenn das Applet sauber signiert ist. Oder könnte es sein, dass man neuerdings auch mit signierten Applets einen Policy-Eintrag machen muss, um die Berechtigung zum lesen und schreiben auf dem lokalen PC zu erhalte?

Ich möchte mit dem Applet eine Datei auf dem lokalen Gerät lesen und diese in der Java Konsole rausschreiben. Wenn ich in der Policy den read-Berechtigung setze, funktioniert alles. Aber ich möchte dies mit einer Signatur erreichen, weil dies für meine Kunden viel einfacher wäre. Das Applet sieht folgendermassen aus:

Java Version: jdk1.7.0_05


```
import java.applet.*;
import java.io.*;
import java.security.*;


public class testapp extends Applet {

 
	public void testapp() throws IOException {
		String filepath = "C:/testdir/test.txt";
		String strread = "";
		int len = (int)(new File(filepath).length());
		
		FileInputStream fis = new FileInputStream(filepath);
		byte buf[] = new byte[len];
		fis.read(buf);
		fis.close();
		strread = new String(buf);
		System.out.println("Text aus File: " + strread);
	}

}
```

Ich rufe das Applet folgendermassen im HTML auf:


```
<html>
<head>
<title>Signed Applet generated by Jaycert v1.0</title>
<meta name="author" content="Jaycert v1.0 by Oliver Sonthof">
</head>
<body style="text-align:center">
<p>
   <a href="certificate.crt">Hier klicken, um das Zertifikat zu installieren!</a><br><br>
   Weitere Informationen zum Importieren des Zertifikats auf <a href="http://www.olison.com/fragen/cacerts.php" target="_blank">olison.com</a>
</p>
<object type="application/x-java-applet;version=1.4.1" name="testappers">
    <param name = "code" value = "testapp.class" >
    <param name = "archive" value = "testapp.jar" >
    <param name = "mayscript" value="yes"> 
    <param name = "scriptable" value = "true">
</object>
<script language="JavaScript">
<!--
	function gotest(){
		document.testappers.testcare();	
	}
-->
</script>
<a href="javascript:gotest();">show text</a>
</body>
</html>
```

Ich habe das Applet folgendermassen signiert:


```
jar cf testapp.jar JarTest1.class testapp.class 
keytool -genkey -keyalg rsa -alias meinKey
keytool -export -alias meinKey -file certifiacat.crt
jarsigner testapp.jar meinKey
```

Leider kommt immer access denied. Das Fehler-File in der Java-Konsole spuckt folgendes aus:
Das Zertifikat habe ich lokal importiert. Leider kommt trotzdem immer access denied exception. Das Fehler-File in der Java-Konsole spuckt folgendes aus:


```
security: property package.access value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.
security: property package.access new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws
security: property package.access value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws
security: property package.access new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy
security: property package.access value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy
security: property package.access new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy,com.sun.jnlp
security: property package.definition value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.
security: property package.definition new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws
security: property package.definition value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws
security: property package.definition new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy
security: property package.definition value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy
security: property package.definition new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy,com.sun.jnlp
security: property package.access value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy,com.sun.jnlp
security: property package.access new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy,com.sun.jnlp,org.mozilla.jss
security: property package.definition value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy,com.sun.jnlp
security: property package.definition new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.javaws,com.sun.deploy,com.sun.jnlp,org.mozilla.jss
basic: Fortschritts-Listener hinzugefügt: sun.plugin.util.ProgressMonitorAdapter@15ab821
basic: Plugin2ClassLoader.addURL parent called for [url]http://localhost/testtool.jar[/url]
security: Blacklist-Entzugsprüfung ist aktiviert
security: Prüfung der Liste vertrauenswürdiger Librarys ist aktiviert
network: Cacheeintrag gefunden [URL: http://localhost/testtool.jar, Version: null] prevalidated=true/0
cache: Resource http://localhost/testtool.jar has expired.
network: Verbindung von http://localhost/testtool.jar mit Proxy=DIRECT wird hergestellt
network: Verbindung von http://localhost:80/ mit Proxy=DIRECT wird hergestellt
network: http://localhost/testtool.jar wird mit Cookie "ASPSESSIONIDASTABCAS=GPMNDFEBGGMEANLLJCECDLMJ" verbunden
network: ResponseCode für http://localhost/testtool.jar: 304
network: Codierung für http://localhost/testtool.jar: null
network: Verbindung mit http://localhost/testtool.jar trennen
cache: Reading Signers from 1010 http://localhost/testtool.jar | C:\Users\marcel\AppData\LocalLow\Sun\Java\Deployment\cache\6.0\60\1bc68e3c-500b096b.idx
cache: Done readSigners(http://localhost/testtool.jar)
cache:  Read manifest for http://localhost/testtool.jar: read=181 full=181
basic: Plugin2ClassLoader.getPermissions CeilingPolicy allPerms
security: Deployment-Zertifikate werden aus C:\Users\marcel\AppData\LocalLow\Sun\Java\Deployment\security\trusted.certs geladen
security: Deployment-Zertifikate aus C:\Users\marcel\AppData\LocalLow\Sun\Java\Deployment\security\trusted.certs geladen
security: Zertifikate werden aus Deployment-Session-Zertifikatspeicher geladen
security: Zertifikate wurden aus Deployment-Session-Zertifikatspeicher geladen
security: Zertifikate werden aus Internet Explorer TrustedPublisher-Zertifikatspeicher geladen
security: Zertifikate wurden aus Internet Explorer TrustedPublisher-Zertifikatspeicher geladen
security: Zertifikatkette mit CertPath-API validieren
security: Zertifikate werden aus Internet Explorer ROOT-Zertifikatspeicher geladen
security: Zertifikate wurden aus Internet Explorer ROOT-Zertifikatspeicher geladen
security: Das Zertifikat ist nicht abgelaufen. Zeitstempelinformationen müssen nicht geprüft werden
security: Zuständigkeitslistendatei gefunden
security: Prüfung auf vertrauenswürdige Erweiterung für dieses Zertifikat starten
security: Vergleich der Zuständigkeitsliste mit diesem Zertifikat starten
security: CRL-Unterstützung ist deaktiviert
security: OCSP-Unterstützung ist deaktiviert
security: Diese OCSP-End Entity-Validierung ist deaktiviert
security: Zertifikat wird im Zertifikatspeicher "Deployment denied" gesucht
security: Zertifikat wird im permanenten Deployment-Zertifikatspeicher gesucht
basic: Applet geladen.
basic: Applet resized and added to parent container
basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 115550 us, pluginInit dt 2593822 us, TotalTime: 2709372 us
basic: Applet initialized
basic: Starting applet
basic: completed perf rollup
basic: Applet made visible
basic: Applet started
basic: Told clients applet is started
```

Eigentlich sieht hier alles gut aus. Die Permission sollte mit getPermissions CeilingPolicy allPerms doch gesetzt sein!? Aber der Security-Manager von Java bleibt hartnäckig.

Ich setze jetzt all meine Hoffnungen auf L-ectron-X.


----------



## Marcel Lübeck (29. Jul 2012)

Ich bin einen Schritt weitergekommen. Wenn ich die lokale Datei direkt mit der Init-Funktion im Applet auslese, funktioniert es. Sprich ich kann auf dem lokalen Gerät eine Datei auslesen oder auch schreiben. Wenn ich die Funktion über das Java-Script aufrufe, dann gibt es beim gleichen signierten Applet einen Access Denied. Hat hier jemand damit schon Erfahrungen gesammelt. Ich rufe das Applet folgendermassen auf:


```
<object type="application/x-java-applet;version=1.4.1" name="testappers">
<param name = "code" value = "testapp.class" >
<param name = "archive" value = "testapp.jar" >
<param name = "mayscript" value="yes"> 
<param name = "scriptable" value = "true">
</object>
<script language="JavaScript">
<!--
function gotest(){
document.testappers.testapp(); 
}
-->
</script>
<a href="javascript:gotest();">show text</a>
```

Höchstwahrscheinlch ist es so, dass der Aufruf von Funktionen eines Applets über JavaScript zwar erlaubt ist, die Permissions vom signierten Applet haben dann aber keine Gültigkeit mehr. Das Applet landet dann direkt in der Sandbox.

Wäre Cool, wenn mir dies jemand bestätigen könnte. Oder noch besser, wenn es doch eine Lösung geben sollte.


----------



## Guest2 (30. Jul 2012)

Moin,

sehr wahrscheinlich ist der calling context aus dem JavaScript nicht dazu berechtigt sicherheitsrelevante Operationen durchzuführen. Das gilt auch wenn das Applet signiert ist. Man kann das mittels [c]AccessController.doPrivileged(new PrivilegedAction() {
..[/c] umgehen. Dabei sollte man sich aber voll bewusst machen, was man da genau macht. Insbesondere:



			
				http://docs.oracle.com/javase/6/docs/api/java/security/AccessController.html hat gesagt.:
			
		

> Be *very* careful in your use of the "privileged" construct, and always remember to make the privileged code section as small as possible.



Die Kombination aus signiertem Applet mit allen rechten und doPrivileged() gehört mit zu dem gefährlichstem, was man sich und seinem Nutzer antun kann.

Wenn es Dir nur um den Zugriff auf die Datei geht, dann siehe Dir die JNLP API an: JNLP API Examples. Dann ist eine Signatur des Applets nicht mehr notwendig!

Viele Grüße,
Fancy


----------



## L-ectron-X (31. Jul 2012)

Das Applet wird außerdem verkehrt eingebunden.
Lies mal dies hier: http://www.java-forum.org/applets/114668-java-applet-webseite-einbinden.html


----------



## Marcel Lübeck (1. Aug 2012)

Hallo Guest2

Super, du hast mir die Lösung Pfannenfertig aufs Tablet gelegt. Der Schlüssel ist AccessController.doPrivileged(new PrivilegedAction(). Damit hat es in jedem Browser funktioniert. Vielen Dank!!!

Danke auch für den Hinweis auf javax.jnlp Das wäre auch ein Lösungsansatz. Ich habe es kurz überflogen. Immer wenn bei meinen Kunden etwas abgespeichert wird, sollte es auf dem lokalen Gerät eine Sicherung anlegen. Falls das Internet einen Unterbruch haben sollte, müssen sie weiterarbeiten können. Mit javax.jnlp würde ja dann immer eine Warnung kommen, wenn etwas online abgespeichert wird. Oder nicht? Meine Kunden wollen sich ja nicht immer mit diesen Warnungen rumschlagen. Deshalb denke ich, dass die bisherige Variante eleganter ist. Ich weiss genau, was ich mache und meine Kunden kennen mich und wissen in diesem Fall auch genau, was sie zu tun haben.

Den zweiten Nachteil sehe ich darin, dass javax nicht im Standart-Java enthalten ist. Ich versuche immer Standart-Funktionen einzusetzen, da ich möchte, dass der Kunde nur Java installieren muss und auch, damit meine Programme auch in 20 Jahren noch laufen. Bei den Zusätzen habe ich Angst, dass dies plötzlich nicht mehr unterstützt wird. Zumal Java ja gratis ist. Dies ist bei javax.comm. schon so geschehen. Das direkte ansteuern eines USB-Ports ist mit .comm.properties nicht mehr möglich. Es gibt dann ein Kevin Hester, der das weiterentwickelt hat. Das wird mir aber zu konfus. Was ist, wenn dieser Kevin Hestler nicht mehr da ist? Dies nur als Beispiel. Mir ist klar, dass es für nichts eine 100%-Sicherheit gibt. Aber mit den Standard-Funktionen fahre ich am sichersten in die Zukunft. Aber vielleicht gibt es auch hier eine andere Sicht.

Hallo L-ectron-x

Es mag sein, dass das Applet verkehrt eingebunden wurde. Es hat aber bei jedem Browser funktioniert. Die lese-Funktion auf das lokale Gerät des Applets braucht in jedem Fall einen AccessController.doPrivileged, wenn es aus JavaScript aufgerufen wird. So wie dies Guest2 erläutert hat. Aber trotzdem vielen Dank für den Hinweis. Ich binde jetzt die Applets genau so ein, wie du das beschrieben hast. Sicher ist sicher.

Vielen Dank nochmals an Guest2 und L-ectron-x für die professionelle Hilfe!


----------



## Guest2 (1. Aug 2012)

Hallo Marcel,

schön das es funktioniert!

Vielleicht noch als Nachtrag zur JNLP API. Diese gehört schon zum normalen Java und wird auch durch die normale JRE zur Verfügung gestellt. Allerdings liegt davon nichts im Classpath und ist auch nicht sichtbar. Der Hintergrund ist, dass das was man da konkret bekommt, vom ausführenden Container abhängig ist. Deshalb mus das jnlp.jar zwar innerhalb der IDE eingebunden werden, zur Laufzeit im Browser (als Applet oder Webstart Anwendung) wird diese jedoch nicht mehr benötigt.

Aber Du hast natürlich recht, die JNLP API fragt bei jedem Zugriff explizit beim Nutzer nach.

Der Nachteil beim Zugriff über den AccessController ist, dass man schnell zu viel freigibt. Z.B. angenommen du hättest dein Code Snippet von oben folgendermaßen verpackt:


```
public String readFile(final String filepath) throws PrivilegedActionException {

        return AccessController.doPrivileged(new PrivilegedExceptionAction<String>() {

            public String run() throws IOException {

                final int len = (int) (new File(filepath).length());
                final FileInputStream fis = new FileInputStream(filepath);
                final byte buf[] = new byte[len];
                fis.read(buf);
                fis.close();
                return new String(buf);

            }
        });

    }
```

Dann sieht das erstmal harmlos aus. Bedeutet aber das jeder beliebige Code dein Applet missbrauchen kann, um jede beliebige Datei auf dem Rechner deines Kunden zu lesen. Wird Dein Kunde z.B. auf eine fremde Webseite gelockt, dann kann ein dortiges "evil" JavaScript über Dein Applet unbemerkt auf den Rechner deines Kunden zugreifen.

Man kann das Risiko minimieren, wenn man jeden Zugriff explizit prüft (z.B. auf welche Dateien zugegriffen werden darf). Dabei mus man aber auch aufpassen das von außen nichts eingeschmuggelt oder manipuliert werden kann.

Der konkrete Aufwand hängt dann von den Sicherheitsanforderungen Deines Kunden ab.

Eine andere Alternative wäre noch das lokale policy file entsprechend anzupassen, um den Zugriff zu erlauben. Aber auch da gibt es Fallstricke, wo aufgepasst werden muss, dass keine Sicherheitslöcher aufgerissen werden.

Viele Grüße,
Fancy


----------



## Marcel Lübeck (2. Aug 2012)

Danke Fancy für die Erläuterungen. Somit könnte ich JNLP bedenkenlos einsetzen. Ich brauche dies aber momentan nicht. Sobald ich wusste, wie ich mit einem signierten Applet eine lokale Datei öffnen oder schreiben kann, war für mein Projekt das Problem gelöst. Es war nur noch Interesse und Neugier zu wissen, wieso dies mit dem JavaScript-Aufruf des Applets nicht funktioniert. Du hast mir jetzt die ganzen Zusammenhänge einfach erklärt.

Ich werde mit diesem signierten Applet (ohne JavaScript-Aufruf und ohne PrivilegedAction) eine Policy-Datei im user-Verzeichnis des lokalen Gerätes erstellen. Dies ist etwas, was der Kunde nur beim 1. Mal macht und dann noch, wenn der Kunde auf einen neuen PC wechselt. Somit kommt das ca. alle 2 Jahre einmal vor, dass dieses Applet benutzt wird. Ein evil JavaScript könnte höchsten dieses Applet von einer anderen Seite aus nochmals starten, was einfach die Policy-Datei nochmals erstellen würde. Hier sehe ich kein Sicherheitsrisiko. Einfach melden, wenn ich mich irren sollte.

Der nächste Schritt ist jetzt das Policy-File. Ich überlege mir jetzt, welche Löcher ich damit aufreissen könnte. Mit dem Policy-File erlaube ich einem neu unter user erstellten Verzeichnis die read,write,delete-Kompetenz. Ein anderes Applet hätte dann diese Kompetenzen in diesem Verzeichnis auch. Grundsätzlich kann ich mit diesem Risiko leben. Ich habe dies die letzten 6 Jahre auch schon getan. Es sind keine sensiblen Daten und wenn die Daten halt alle gelöscht würden, würde der Server die Dateien autom. wieder anlegen. Ich könnte also ruhig warten bis ein solcher Fall mal auftritt, und dann die Sicherheit nochmals verstärken. Was ich aber jetzt schon machen möchte, ist ein signedby im Policy-File. Ich möchte, dass nur dieses Applet auf dieses Verzeichnis zugreiffen kann. Das müsste ja mit signedby möglich sein. Damit ich ein Signedby definieren kann, muss das Applet ja signiert sein. Aber wenn das Applet signiert ist, hat es ja sowieso schon den vollen Zugriff auf die Festplatte? Wie kriege ich es jetzt hin, dass das signierte Applet nur Zugriff auf dieses Verzeichnis hat und nicht gleich auf die ganze Platte?

Danke für Hinweise auf Sicherheitsrisiken. Vielleicht gäbe es ja ganz andere Lösungsansätze. Es ist natürlich toll, wenn du mich mit deinem profunden Fachwissen unterstützen könntest. Wie gesagt, ich bin ein Anfänger in Java.


----------



## Guest2 (2. Aug 2012)

Marcel Lübeck hat gesagt.:


> Ich werde mit diesem signierten Applet (ohne JavaScript-Aufruf und ohne PrivilegedAction) eine Policy-Datei im user-Verzeichnis des lokalen Gerätes erstellen.



Hm, hast Du mal ausprobiert, ob das geht? Ich meine mich nämlich zu erinnern, dass aus der Sandbox heraus eine direkte Modifikation der policy files verhindert wird (auch wenn der Code signiert ist). Allgemein ist das Verteilen der policy files aber auch ehr etwas für die verantwortlichen Admins. Diese können die (ggf. zusammen mit der trusted.policy) und der JRE ausrollen.




Marcel Lübeck hat gesagt.:


> Was ich aber jetzt schon machen möchte, ist ein signedby im Policy-File. Ich möchte, dass nur dieses Applet auf dieses Verzeichnis zugreiffen kann. Das müsste ja mit signedby möglich sein. Damit ich ein Signedby definieren kann, muss das Applet ja signiert sein. Aber wenn das Applet signiert ist, hat es ja sowieso schon den vollen Zugriff auf die Festplatte? Wie kriege ich es jetzt hin, dass das signierte Applet nur Zugriff auf dieses Verzeichnis hat und nicht gleich auf die ganze Platte?



Genau, signiert haben Applets erstmal fast alle Rechte. Für Heimanwender mag das ok sein, bei Firmen kann dies aber ggf. gegen die Sicherheitsrichtlinien verstoßen. Deshalb besteht die Möglichkeit eine trusted policy zu definieren, in welcher geregelt werden kann was signierte Anwendungen genau dürfen. Diese policy muss über den Schlüssel [c]deployment.security.trusted.policy[/c] in der  [c]deployment.properties[/c] eingebunden werden (Deployment Configuration File and Properties
)(unter Windows: [c]C:\Users\Fancy\AppData\LocalLow\Sun\Java\Deployment\deployment.properties[/c]).

Eine andere Möglichkeit wäre auch noch die Einschränkung über den codeBase Eintrag in der policy. Dazu muss das Applet nicht signiert sein, schützt jedoch auch nicht vor einer Manipulation des Applets.




Marcel Lübeck hat gesagt.:


> Danke für Hinweise auf Sicherheitsrisiken. Vielleicht gäbe es ja ganz andere Lösungsansätze.



Wenn Du keine Aufrufe aus einem anderen calling context verarbeiten musst (also z.B. kein JavaScript oder unsigniertem Code) also auch kein PrivilegedAction benötigst, dann wird das einfacher. Du kannst in das Manifest deines Jars die Attribute [c]Trusted-Only: true[/c] (verhindert das Dein Code mit unsigniertem Code in Berührung kommen kann) und [c]Sealed: true[/c] (verhindert das Klassen aus anderen Quellen in deine Packet Definition eindringen können) eintragen. Dadurch wird verhindert das Dein Code von außen manipuliert werden kann (z.B. durch Reflection). Dann könntest Du dein Jar auch wieder bedenkenlos signieren.  

Viele Grüße,
Fancy


----------



## Marcel Lübeck (3. Aug 2012)

Hm, hast Du mal ausprobiert, ob das geht?
Ja ich kann eine java.policy im User-Verzeichnis unter Windows 7 und auch unter Windows XP erstellen. Die Berechtigungen habe ich im User-Verzeichnis seit der Installation des OS nicht verändert. Ob es bei Linux oder Mac funktioniert, muss ich noch testen. Bei grösseren Unternehmen funktioniert das natürlich nicht. Da müsste ich dies dann mit den Administratoren besprechen.

Danke für die Erklärungen betr. deployment.security. Gut zu wissen, dass es dies gibt.

Deine vorgeschlagene Variante wäre zwar die Sicherste, ich brauche aber JavaScript. Ich habe ja 2 Applets. Das eine, das signiert ist und nur eine java.policy im User-Verzeichnis erstellt. Von aussen werden keine Parameter übergeben. Dieses Applet wird nur bei einer Neuinstallation gebraucht. Das 2. Applet soll unsigniert sein und hat JavaScript-Aufrufe. Unsigniert muss es sein, da die Kunden dann plötzlich die Erlaubnis nicht geben würden und dann würden die Daten auf dem lokalen Gerät nicht synchronisiert. Bei einem Internetausfall hätte der Kunde dann keine Offline-Sicherheit und dies wäre die schlimmste Sicherheitslücke.

Du hast mir mit CodeBase schon einen wichtigen Hinweis gegeben. So kann ich absichern, dass nur mein Applet Zugriff auf das in der java.policy geöffneten Verzeichnis hat. Ich möchte aber auch noch absichern, dass mein Applet nicht von einer anderen HTML-Seite im Netz ausgeführt werden kann. Das wäre ja eigentlich das Sealed: true im Manifest, wenn ich das richtig verstanden habe. Aber das funktioniert nur bei einer signierter jar-Datei. Ich möchte genau das ohne Signatur?! Im policy-file kann dies nach dem gleichen Prinzip wie CodeBase wahrscheinlich nicht definiert werden, sonst hättest du das erwähnt. Somit könnte ich dies im Applet mit getDocumentBase() selber absichern? So könnte das Applet nicht mehr manipuliert werden. Sehe ich das soweit richtig?


----------



## Guest2 (4. Aug 2012)

Mit [c]Sealed: true[/c] im Manifest wird lediglich sichergestellt das alle Klassen eines package aus demselben JAR geladen werden. Woher dieses JAR geladen wird, wird dabei aber nicht berücksichtigt. Es schützt also z.B. davor, dass eine fremde Klasse aus einem fremden JAR eine eigene Klasse "austauscht / überschreibt". Grundsätzlich ist diese Angabe auch in einem unsigniertem JAR möglich. Sicherheitstechnisch ist sie dann jedoch weniger stark, da ein Angreifer die Zeile einfach aus dem Manifest entfernen könnte. 

Dasselbe gilt für Deine Idee mit dem getDocumentBase(). Ein Angreifer kann relativ problemlos dein JAR entpacken, dekompilieren, die Abfrage entfernen, kompilieren und auf seiner Seite neu einbinden. Allerdings würde dann die codeBase Angabe im policy file nicht mehr greifen, so das ein Zugriff auf die Verzeichnisse Deines Kunden nicht mehr möglich ist.

Ausgeführt werden kann Deine Anwendung aber immer.

Viele Grüße,
Fancy


----------



## Marcel Lübeck (4. Aug 2012)

Gut, nun habe ich dank dir alle Zusammenhänge beisammen. Dass das Applet mit dem entsprechenden gezielten Aufwand noch ausgeführt werden kann, ist nicht weiter schlimm. Das Wichtigste ist, dass niemand mehr auf das Verzeichnis zugreiffen kann. Ich benötige ja keine einbruchsichere Tresortüre sondern nur eine Bürotüre, die abeschlossen werden kann. Ich könnte das Applet wahrscheinlich auch ohne JavaScript-Zugriffe programmieren. Das Problem ist, dass ich dies vor 6 Jahren schon programmiert habe und alles sonst gut funktioniert. Der Aufwand wäre sehr gross, dies nur für eine Tresortüre umzuprogrammieren, wenn es ja gar keine Tresortüre braucht. Falls ich noch viele Neukunden haben sollte, würde sich dieser Aufwand sicher mal lohnen. Ob ich das dann aus Zeitgründen noch selber machen kann, ist fraglich. Vielleicht werde ich dann in diesem Forum nach jemandem auschau halten, der dies machen könnte.

Nochmals vielen Dank an Fancy für die umfassenden und pickfeinen Erklärungen. Ich hoffe, du bist wieder da, wenn ich wieder mal ein Java-Problem habe.


----------

