Skip to content

Conversation

@sgrampone
Copy link
Contributor

codeql

@genexusbot
Copy link
Collaborator

Cherry pick to beta failed, 1 conflicted file in commit 91e3b12
  • gxcompress/src/main/java/com/genexus/compression/GXCompressor.java

log.error(DIRECTORY_ATTACK + "{}", entry.getName());
return;
}else {
File newFile = new File(directory, entry.getName());

Check failure

Code scanning / CodeQL

Arbitrary file access during archive extraction ("Zip Slip") High

Unsanitized archive entry, which may contain '..', is used in a
file system operation
.
Unsanitized archive entry, which may contain '..', is used in a
file system operation
.
Unsanitized archive entry, which may contain '..', is used in a
file system operation
.
Unsanitized archive entry, which may contain '..', is used in a
file system operation
.
Unsanitized archive entry, which may contain '..', is used in a
file system operation
.

Copilot Autofix

AI 14 days ago

To fix the Zip Slip vulnerability, we need to ensure that output paths created using an archive entry's name are securely validated before performing any file system operation. The best way to do this is:

  • For every extracted file (across tar, 7z, jar), construct the destination file path and normalize it.
  • Check whether the normalized path is under the intended extraction directory by comparing path prefixes (Path.startsWith() or equivalent using canonical path).
  • If the path does not start with the intended extraction directory, abort extraction of that entry and possibly log or throw an exception.
  • Implement this in both decompress7z (for each SevenZArchiveEntry) and decompressJar (for each JarEntry), similar to how it is done (perhaps in an auxiliary method) for tar files.

In particular, the following regions require fixes:

  • In decompress7z, after creating newFile, validate it before any file system operation.
  • In decompressJar, after creating outputFile, validate it before any file system operation.

Code imports required:

  • Ensure that java.nio.file.Path is imported (already is).
  • Use toPath().normalize() and compare with the extraction directory's canonical path.

If there's already a helper utility for path traversal check (CompressionUtils.isPathTraversal), use that for cross-format consistency. If not, implement a simple helper locally in this file.


Suggested changeset 1
gxcompress/src/main/java/com/genexus/compression/GXCompressor.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -613,6 +613,11 @@
 		try (SevenZFile sevenZFile = new SevenZFile(archive)) {
 			SevenZArchiveEntry entry;
 			while ((entry = sevenZFile.getNextEntry()) != null) {
+				// Added Zip Slip protection for 7z extraction
+				if (CompressionUtils.isPathTraversal(directory, entry.getName())) {
+					log.error(DIRECTORY_ATTACK + "{}", entry.getName());
+					continue;
+				}
 				File newFile = new File(directory, entry.getName());
 				if (entry.isDirectory()) {
 					if (!newFile.isDirectory() && !newFile.mkdirs()) {
@@ -771,6 +776,11 @@
 		try (JarInputStream jarInputStream = new JarInputStream(Files.newInputStream(archive.toPath()))) {
 			JarEntry entry;
 			while ((entry = jarInputStream.getNextJarEntry()) != null) {
+				// Added Zip Slip protection for jar extraction
+				if (CompressionUtils.isPathTraversal(targetDir.getAbsolutePath(), entry.getName())) {
+					log.error(DIRECTORY_ATTACK + "{}", entry.getName());
+					continue;
+				}
 				File outputFile = new File(targetDir, entry.getName());
 				if (entry.isDirectory()) {
 					if (!outputFile.exists() && !outputFile.mkdirs()) {
EOF
@@ -613,6 +613,11 @@
try (SevenZFile sevenZFile = new SevenZFile(archive)) {
SevenZArchiveEntry entry;
while ((entry = sevenZFile.getNextEntry()) != null) {
// Added Zip Slip protection for 7z extraction
if (CompressionUtils.isPathTraversal(directory, entry.getName())) {
log.error(DIRECTORY_ATTACK + "{}", entry.getName());
continue;
}
File newFile = new File(directory, entry.getName());
if (entry.isDirectory()) {
if (!newFile.isDirectory() && !newFile.mkdirs()) {
@@ -771,6 +776,11 @@
try (JarInputStream jarInputStream = new JarInputStream(Files.newInputStream(archive.toPath()))) {
JarEntry entry;
while ((entry = jarInputStream.getNextJarEntry()) != null) {
// Added Zip Slip protection for jar extraction
if (CompressionUtils.isPathTraversal(targetDir.getAbsolutePath(), entry.getName())) {
log.error(DIRECTORY_ATTACK + "{}", entry.getName());
continue;
}
File outputFile = new File(targetDir, entry.getName());
if (entry.isDirectory()) {
if (!outputFile.exists() && !outputFile.mkdirs()) {
Copilot is powered by AI and may make mistakes. Always verify output.
@sgrampone sgrampone closed this Nov 27, 2025
@sgrampone sgrampone deleted the fix/gxcompress-codeql branch November 27, 2025 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants