<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
</head>
<body>
<div dir="ltr">
<div></div>
<div>
<div>Rick if you fear an attacker can modify and install a JAR with a broken signature which you don’t trust anyway, what should stop the attacker to provide a valid but untrusted signature or no checksums at all? It might be a undesirable change for your case
 but I see no trustmodel where you would need default java classloader to do more than treating it unsigned.</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">But if you really want to re-enable SHA1 you can do so (or implement a classloader which rejects any SHA1 codebases). Of course much easier would be to only install verified jars.</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">BTW the fact that you actually get answers about a weakness report is amazing :)</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">Gruss</div>
<div dir="ltr">Bernd</div>
<div id="ms-outlook-mobile-signature">
<div style="direction:ltr">-- </div>
<div style="direction:ltr">http://bernd.eckenfels.net</div>
</div>
</div>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>Von:</b> security-dev <security-dev-retn@openjdk.java.net> im Auftrag von Rick Hillegas <rick.hillegas@gmail.com><br>
<b>Gesendet:</b> Wednesday, November 3, 2021 6:07:00 PM<br>
<b>An:</b> Sean Mullan <sean.mullan@oracle.com>; security-dev@openjdk.java.net <security-dev@openjdk.java.net><br>
<b>Betreff:</b> Re: previously prevented exploit now possible with JDK 18</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Thanks for your detailed comments, Sean. We agree wholeheartedly that
<br>
being signed and being trusted/valid are two separate concepts. The JDK <br>
wisely punts the issue of trust to the application developer. As I <br>
understand it, we disagree about the following points:<br>
<br>
1) Is the signedness of a jar an immutable fact or is it just an <br>
opinion? I think that it is an immutable fact, measured by whether the <br>
jar's manifest contains certain stereotypical files. You maintain that <br>
it is an opinion which can shift incompatibly between JDK releases.<br>
<br>
2) Should the JDK continue to raise an exception when loading classes <br>
from clearly compromised jars?<br>
<br>
3) Are javadoc and a release note adequate defenses against an exploit <br>
which will surface when a mission-critical application upgrades to a JDK <br>
containing the work on <a href="https://bugs.openjdk.java.net/browse/JDK-8269039">
https://bugs.openjdk.java.net/browse/JDK-8269039</a> ?<br>
<br>
Here's how I see it:<br>
<br>
a) A jar doesn't cease to be signed when its signer goes to jail and <br>
authorities revoke the signing certificate.<br>
<br>
b) A jar doesn't cease to be signed because someone pokes malware into <br>
it and breaks the hash.<br>
<br>
c) A jar doesn't cease to be signed because serious people distrust its <br>
old, shoddy cryptography.<br>
<br>
In all of these cases, trust has diminished. But the jar is still signed.<br>
<br>
Note that the emphatic deprecation of the SecurityManager affects your <br>
comments below.<br>
<br>
Thanks,<br>
-Rick<br>
<br>
<br>
On 11/2/21 11:34 AM, Sean Mullan wrote:<br>
> Hello Rick,<br>
><br>
> It is behaving as expected. Let me explain in more detail.<br>
><br>
> First, loading a signed JAR off the classpath only verifies the<br>
> signature and digests of the JAR file. It does not validate the signer's<br>
> certificate chain or determine if the signer is trusted. The JarFile API<br>
> class description includes this warning [1]:<br>
><br>
> "Please note that the verification process does not include validating<br>
> the signer's certificate. A caller should inspect the return value of<br>
> JarEntry.getCodeSigners() to further determine if the signature can be<br>
> trusted."<br>
><br>
> Some frameworks such as Web Start have this additional checking<br>
> built-in. Or, if you run your code with a Security Manager, then<br>
> additional steps will be performed at run-time to check that the code is<br>
> signed and that the signer's public key is trusted before granting<br>
> permissions to that code.<br>
><br>
> If you don't perform these additional steps, then the JAR can be<br>
> modified without detection. For example, the signature related files<br>
> could be removed from the JAR (thus making it an unsigned JAR), or the<br>
> JAR could be modified and then re-signed with a different key. In either<br>
> of these cases, the JVM would load the JAR without any exception.<br>
><br>
> It is also possible that a JAR signed with a weak or broken algorithm <br>
> (such as MD5 or SHA-1) could be modified without detection.<br>
><br>
> This is why the JDK implementation supports several security<br>
> properties which are used to disable cryptographic algorithms and<br>
> protocols that are weak or broken. This provides out-of-the-box security<br>
> and is important to safeguard against crypto algorithms that inevitably<br>
> become weaker over time. One of these properties is<br>
> "jdk.jar.disabledAlgorithms". The specification of this property defines<br>
> the behavior if a signed JAR file is signed with an algorithm that is<br>
> disabled [2]:<br>
><br>
> "JARs signed with any of the disabled algorithms or key sizes will be<br>
> treated as unsigned."<br>
><br>
> The JDK determined after step 1 of the JAR verification process [3] that<br>
> the JAR was signed with SHA-1, and therefore stopped further processing.<br>
><br>
> You may ask why we don't throw an Exception in this case. Although this<br>
> was considered, the compatibility risk was too high. These<br>
> restrictions are nearly always backported to earlier JDK update<br>
> releases. Throwing an Exception would be too high of a risk for<br>
> applications that happen to load signed JARs off the classpath but don't<br>
> otherwise behave any differently. Our primary focus is to protect<br>
> applications that verify that the code is signed by someone they trust.<br>
><br>
> Consider updating and re-signing your signed jar with a stronger, <br>
> non-broken algorithm such as SHA-2. SHA-2 is the default digest <br>
> algorithm used by jarsigner when the -digestalg option is not specified.<br>
><br>
> I hope this information is useful. I do think this is an area where our<br>
> javadocs and guides could be improved to provide more information about<br>
> how signed JARs are verified including more details on the behavior of<br>
> the JDK implementation with respect to disabled algorithms. We will be<br>
> working to try to improve the docs for JDK 18.<br>
><br>
> --Sean<br>
><br>
> [1]<br>
> <a href="https://download.java.net/java/early_access/jdk18/docs/api/java.base/java/util/jar/JarFile.html">
https://download.java.net/java/early_access/jdk18/docs/api/java.base/java/util/jar/JarFile.html</a>
<br>
><br>
> [2]<br>
> <a href="https://github.com/openjdk/jdk/blob/master/src/java.base/share/conf/security/java.security#L667">
https://github.com/openjdk/jdk/blob/master/src/java.base/share/conf/security/java.security#L667</a>
<br>
><br>
> [3]<br>
> <a href="https://docs.oracle.com/en/java/javase/17/docs/specs/jar/jar.html#signed-jar-file">
https://docs.oracle.com/en/java/javase/17/docs/specs/jar/jar.html#signed-jar-file</a>
<br>
><br>
><br>
><br>
> On 10/28/21 3:14 PM, Rick Hillegas wrote:<br>
>> As a canary in the mineshaft, I built and tested Apache Derby with the<br>
>> recent build 18-ea+20-1248 of Open JDK 18. I tripped across the<br>
>> following issue when running Derby's regression tests. The problem is<br>
>> explained in more detail at<br>
>> <a href="https://issues.apache.org/jira/browse/DERBY-7126">https://issues.apache.org/jira/browse/DERBY-7126</a>, where a simple repro<br>
>> (DERBY_7126_A) can be found. The problem is almost surely the result of<br>
>> work done on <a href="https://bugs.openjdk.java.net/browse/JDK-8269039">https://bugs.openjdk.java.net/browse/JDK-8269039</a> (Disable<br>
>> SHA-1 Signed JARs).<br>
>><br>
>> Under previous versions of the JDK, the JVM would raise an error if you<br>
>> tried to load a class from a jar file which had been signed with SHA-1<br>
>> but later hacked by inserting malware via "jar -uf". This was the error:<br>
>><br>
>>     SHA1 digest error for $corruptedJarFileName<br>
>><br>
>> However, under JDK 18 the hacked class loads, no error is raised, and<br>
>> the malware can now be executed. I was surprised that a previously<br>
>> prevented exploit now works. I think it would be better if the JVM still<br>
>> refused to load the hacked class even though SHA-1 has been deprecated.<br>
>><br>
>> Thanks,<br>
>> -Rick<br>
>><br>
<br>
</div>
</span></font></div>
</body>
</html>