mirror of
https://github.com/corda/corda.git
synced 2024-12-20 05:28:21 +00:00
Tighten no overlap check. (#4690)
This commit is contained in:
parent
deba96dce9
commit
37eb93fa76
@ -50,12 +50,21 @@ class AttachmentsClassLoader(attachments: List<Attachment>, parent: ClassLoader
|
||||
private val ignoreDirectories = listOf("org/jolokia/", "org/json/simple/")
|
||||
private val ignorePackages = ignoreDirectories.map { it.replace("/", ".") }
|
||||
|
||||
private fun shouldCheckForNoOverlap(path: String, targetPlatformVersion: Int) = when {
|
||||
// This function attempts to strike a balance between security and usability when it comes to the no-overlap rule.
|
||||
// TODO - investigate potential exploits.
|
||||
private fun shouldCheckForNoOverlap(path: String, targetPlatformVersion: Int): Boolean {
|
||||
require(path.toLowerCase() == path)
|
||||
require(!path.contains("\\"))
|
||||
|
||||
return when {
|
||||
path.endsWith("/") -> false // Directories (packages) can overlap.
|
||||
targetPlatformVersion < 4 && ignoreDirectories.any { path.startsWith(it) } -> false // Ignore jolokia and json-simple for old cordapps.
|
||||
path.endsWith(".class") -> true // All class files need to be unique.
|
||||
!path.startsWith("meta-inf") -> true // All files outside of Meta-inf need to be unique.
|
||||
else -> false // This allows overlaps over any non-class files in "Meta-inf".
|
||||
!path.startsWith("meta-inf") -> true // All files outside of META-INF need to be unique.
|
||||
(path == "meta-inf/services/net.corda.core.serialization.serializationwhitelist") -> false // Allow overlapping on the SerializationWhitelist.
|
||||
path.startsWith("meta-inf/services") -> true // Services can't overlap to prevent a malicious party from injecting additional implementations of an interface used by a contract.
|
||||
else -> false // This allows overlaps over any non-class files in "META-INF" - except 'services'.
|
||||
}
|
||||
}
|
||||
|
||||
private fun requireNoDuplicates(attachments: List<Attachment>) {
|
||||
|
@ -14,6 +14,7 @@ import net.corda.testing.services.MockAttachmentStorage
|
||||
import org.apache.commons.io.IOUtils
|
||||
import org.junit.Assert.assertArrayEquals
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
@ -116,6 +117,36 @@ class AttachmentsClassLoaderTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Overlapping rules for META-INF serializationwhitelist files`() {
|
||||
val att1 = importAttachment(fakeAttachment("meta-inf/services/net.corda.core.serialization.serializationwhitelist", "some data").inputStream(), "app", "file1.jar")
|
||||
val att2 = importAttachment(fakeAttachment("meta-inf/services/net.corda.core.serialization.serializationwhitelist", "some other data").inputStream(), "app", "file2.jar")
|
||||
|
||||
AttachmentsClassLoader(arrayOf(att1, att2).map { storage.openAttachment(it)!! })
|
||||
}
|
||||
|
||||
@Ignore("Enable once `requireNoDuplicates` is fixed. The check is currently skipped due to the incorrect logic.")
|
||||
@Test
|
||||
fun `Overlapping rules for META-INF random service files`() {
|
||||
val att1 = importAttachment(fakeAttachment("meta-inf/services/com.example.something", "some data").inputStream(), "app", "file1.jar")
|
||||
val att2 = importAttachment(fakeAttachment("meta-inf/services/com.example.something", "some other data").inputStream(), "app", "file2.jar")
|
||||
|
||||
assertFailsWith(TransactionVerificationException.OverlappingAttachmentsException::class) {
|
||||
AttachmentsClassLoader(arrayOf(att1, att2).map { storage.openAttachment(it)!! })
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Added test that was removed when the hash-2-signature constraint was added. Enable once `requireNoDuplicates` is fixed.")
|
||||
@Test
|
||||
fun `Test overlapping file exception`() {
|
||||
val att1 = storage.importAttachment(fakeAttachment("file1.txt", "some data").inputStream(), "app", "file1.jar")
|
||||
val att2 = storage.importAttachment(fakeAttachment("file1.txt", "some other data").inputStream(), "app", "file2.jar")
|
||||
|
||||
assertFailsWith(TransactionVerificationException.OverlappingAttachmentsException::class) {
|
||||
AttachmentsClassLoader(arrayOf(att1, att2).map { storage.openAttachment(it)!! })
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Check platform independent path handling in attachment jars`() {
|
||||
val att1 = importAttachment(fakeAttachment("/folder1/foldera/file1.txt", "some data").inputStream(), "app", "file1.jar")
|
||||
|
Loading…
Reference in New Issue
Block a user