Skip to content

Commit

Permalink
GHSA-frvj-cfq4-3228 Skip potentially malicious files in javadoc archives
Browse files Browse the repository at this point in the history
  • Loading branch information
dzikoysk committed May 3, 2024
1 parent e172ae4 commit 8481737
Showing 1 changed file with 30 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ import com.reposilite.shared.badRequest
import com.reposilite.shared.badRequestError
import com.reposilite.shared.errorResponse
import com.reposilite.shared.notFound
import com.reposilite.status.FailureFacade
import com.reposilite.storage.api.FileType.FILE
import com.reposilite.storage.api.Location
import com.reposilite.storage.api.toLocation
import com.reposilite.storage.getSimpleName
import com.reposilite.token.AccessTokenIdentifier
import io.javalin.http.HttpStatus.INTERNAL_SERVER_ERROR
import panda.std.Result
import panda.std.asSuccess
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.util.jar.JarFile
import kotlin.io.path.outputStream
import panda.std.Result
import panda.std.asSuccess

private const val INDEX_FILE = "index.html"

Expand All @@ -33,6 +34,7 @@ internal class JavadocContainer(
)

internal class JavadocContainerService(
private val failureFacade: FailureFacade,
private val mavenFacade: MavenFacade,
private val javadocFolder: Path
) {
Expand Down Expand Up @@ -116,24 +118,39 @@ internal class JavadocContainerService(
!jarPath.getSimpleName().contains("javadoc.jar") -> badRequestError("Invalid javadoc jar! Name must contain: 'javadoc.jar'")
Files.isDirectory(jarPath) -> badRequestError("JavaDoc jar path has to be a file!")
!Files.isDirectory(javadocUnpackPath) -> badRequestError("Destination must be a directory!")

else -> jarPath.toAbsolutePath().toString()
.let { JarFile(it) }
.use { jarFile ->
if (!hasIndex(jarFile)) {
return errorResponse(INTERNAL_SERVER_ERROR, "Invalid javadoc.jar given for extraction")
}

jarFile.entries().asSequence().forEach { file ->
if (file.isDirectory) {
return@forEach
jarFile
.entries()
.asSequence()
.forEach { file ->
if (file.isDirectory) {
return@forEach
}

// GHSA-frvj-cfq4-3228: treat archive file name as external path that can be malicious
val processedArchiveFileLocation = file.name.toLocation()

processedArchiveFileLocation
.toPath()
.map { javadocUnpackPath.resolve(it) }
.peek {
it.parent?.also { parent -> Files.createDirectories(parent) }
jarFile.getInputStream(file).copyToAndClose(it.outputStream())
}
.onError {
failureFacade.throwException(
"Malicious resource path detected: $processedArchiveFileLocation in $jarPath",
IllegalArgumentException("Malicious resource path detected: $it")
)
}
}

val path = Paths.get(javadocUnpackPath.toString() + "/" + file.name)

path.parent?.also { parent -> Files.createDirectories(parent) }
jarFile.getInputStream(file).copyToAndClose(path.outputStream())
}.asSuccess<Unit, ErrorResponse>()
.asSuccess<Unit, ErrorResponse>()
}
.also { Files.deleteIfExists(jarPath) }
}
Expand Down

1 comment on commit 8481737

@dzikoysk
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GHSL-2024-073

Please sign in to comment.