Skip to content

Chen keinan feat new cli support#182

Closed
NickJosevski wants to merge 8 commits into
mainfrom
chen-keinan-feat-new-cli-support
Closed

Chen keinan feat new cli support#182
NickJosevski wants to merge 8 commits into
mainfrom
chen-keinan-feat-new-cli-support

Conversation

@NickJosevski

Copy link
Copy Markdown
Contributor

in repo copy of Chen's PR

chen-keinan and others added 8 commits February 12, 2026 16:29
Signed-off-by: Chen Keinan <hen.keinan@gmail.com>
Signed-off-by: Chen Keinan <hen.keinan@gmail.com>
Signed-off-by: Chen Keinan <hen.keinan@gmail.com>
Signed-off-by: Chen Keinan <hen.keinan@gmail.com>
Signed-off-by: Chen Keinan <hen.keinan@gmail.com>
Signed-off-by: Chen Keinan <hen.keinan@gmail.com>
Signed-off-by: Chen Keinan <hen.keinan@gmail.com>
byte[] buffer = new byte[4096];

while ((entry = tarIn.getNextTarEntry()) != null) {
Path entryPath = destDir.resolve(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
.

Copilot Autofix

AI 5 months ago

In general, to fix Zip Slip / tar-slip vulnerabilities, you must validate that any path created from an archive entry name stays within the intended destination directory. This is typically done by resolving the entry path against the destination directory, normalizing it (or using canonical paths), and then checking that the resulting path starts with the destination directory path. If it does not, you should reject the entry (e.g., throw an exception or skip it).

For this specific code, the best low-impact fix is:

  1. After computing entryPath = destDir.resolve(entry.getName());, normalize the path (e.g., entryPath.normalize()).
  2. Check that the normalized path starts with destDir.normalize() using Path.startsWith(...). Using Path rather than string operations ensures segment-wise matching.
  3. If the check fails, throw an IOException indicating a bad entry, and do not create directories or files for that entry.
  4. Use the validated, normalized entryPath for subsequent filesystem operations (Files.createDirectories(...), Files.newOutputStream(...)).

This change should be implemented within extractTarGzResource in octopus-agent/src/main/java/octopus/teamcity/agent/EmbeddedResourceExtractor.java, right after line 154 where entryPath is currently defined. No new external dependencies are required; everything can be done with java.nio.file.Path, which is already imported. The functional behavior for valid archives remains the same, while malicious or malformed entries are now rejected.

Suggested changeset 1
octopus-agent/src/main/java/octopus/teamcity/agent/EmbeddedResourceExtractor.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/octopus-agent/src/main/java/octopus/teamcity/agent/EmbeddedResourceExtractor.java b/octopus-agent/src/main/java/octopus/teamcity/agent/EmbeddedResourceExtractor.java
--- a/octopus-agent/src/main/java/octopus/teamcity/agent/EmbeddedResourceExtractor.java
+++ b/octopus-agent/src/main/java/octopus/teamcity/agent/EmbeddedResourceExtractor.java
@@ -151,8 +151,13 @@
                 byte[] buffer = new byte[4096];
 
                 while ((entry = tarIn.getNextTarEntry()) != null) {
-                    Path entryPath = destDir.resolve(entry.getName());
+                    Path entryPath = destDir.resolve(entry.getName()).normalize();
+                    Path normalizedDestDir = destDir.toAbsolutePath().normalize();
 
+                    if (!entryPath.toAbsolutePath().normalize().startsWith(normalizedDestDir)) {
+                        throw new IOException("Entry is outside of the target dir: " + entry.getName());
+                    }
+
                     if (entry.isDirectory()) {
                         Files.createDirectories(entryPath);
                     } else {
EOF
@@ -151,8 +151,13 @@
byte[] buffer = new byte[4096];

while ((entry = tarIn.getNextTarEntry()) != null) {
Path entryPath = destDir.resolve(entry.getName());
Path entryPath = destDir.resolve(entry.getName()).normalize();
Path normalizedDestDir = destDir.toAbsolutePath().normalize();

if (!entryPath.toAbsolutePath().normalize().startsWith(normalizedDestDir)) {
throw new IOException("Entry is outside of the target dir: " + entry.getName());
}

if (entry.isDirectory()) {
Files.createDirectories(entryPath);
} else {
Copilot is powered by AI and may make mistakes. Always verify output.
String folderPrefix = resourceFolder.endsWith("/") ? resourceFolder : resourceFolder + "/";

return jarFile.stream()
.map(JarEntry::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
.

Copilot Autofix

AI 5 months ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

@chen-keinan

Copy link
Copy Markdown
Contributor

Duplicate to #183

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants