Fix Zip Slip vulnerability in archive extraction - #296

Merged
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability
Nov 9, 2025
Merged

Fix Zip Slip vulnerability in archive extraction#296
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability

Conversation

CopilotAI commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

Summary

Fixes the Zip Slip vulnerability (arbitrary file write during archive extraction) in the Expand class by improving path validation to prevent directory traversal attacks.

Resolves: https://github.com/codehaus-plexus/plexus-utils/security/code-scanning/1

Problem

The Zip Slip vulnerability is a form of directory traversal attack that allows a malicious zip file to write files outside the intended extraction directory. The original validation in Expand.extractFile() was insufficient:

if (!f.getAbsolutePath().startsWith(dir.getAbsolutePath())) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}

This check had two critical flaws:

  1. Used absolute paths instead of canonical paths: Didn't account for symbolic links or path normalization
  2. Vulnerable to prefix matching: A malicious entry could write to /tmp/extract-evil/malicious.txt when extracting to /tmp/extract because the absolute path string starts with the target directory prefix

Solution

The fix uses canonical paths and adds a file separator to the directory path check to prevent prefix matching attacks:

try {
StringcanonicalDirPath = dir.getCanonicalPath();
StringcanonicalFilePath = f.getCanonicalPath();
// Ensure the file is within the target directory// We need to check that the canonical file path starts with the canonical directory path// followed by a file separator to prevent path traversal attacksif (!canonicalFilePath.startsWith(canonicalDirPath + File.separator)
&& !canonicalFilePath.equals(canonicalDirPath)) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}
} catch (IOExceptione) {
thrownewIOException("Failed to verify entry path for '" + entryName + "'", e);
}

Test Coverage

Added comprehensive test cases in ExpandTest.java:

  • Parent directory traversal attacks (../../evil.txt)
  • Absolute path attacks
  • Prefix matching attacks (extracting to similarly-named directories)
  • Regression test for normal zip extraction

Verification

  • ✅ All 249 tests pass (4 new + 245 existing)
  • ✅ CodeQL security scan confirms 0 vulnerabilities
  • ✅ Code formatting and build checks pass
  • ✅ No breaking changes to existing functionality

The fix is minimal and surgical, changing only 13 lines in the security-critical path validation logic.

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")</issue_title>
<issue_description>

Tracking issue for:

Comments on the Issue (you are @copilot in this section)

Fixes#248


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

CopilotAIand others added 2 commits October 10, 2025 20:39
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix code scanning alert for Zip Slip vulnerabilityFix Zip Slip vulnerability in archive extractionOct 10, 2025
CopilotAI requested a review from slachiewiczOctober 10, 2025 20:46
@slachiewicz
slachiewicz marked this pull request as ready for review October 11, 2025 08:49
@slachiewiczslachiewicz added the bug Something isn't working label Nov 9, 2025
@slachiewicz
slachiewicz merged commit 6d780b3 into masterNov 9, 2025
17 checks passed
@slachiewicz
slachiewicz deleted the copilot/fix-zip-slip-vulnerability branch November 9, 2025 11:32
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
@cstamas

Copy link
Copy Markdown
Member

Can we have this backported to 3.x line as well?

@cstamas

Copy link
Copy Markdown
Member

NVM, missed it is already backported to 3.x

@gsmet

Copy link
Copy Markdown

@cstamas it has been backported but I don't see a 3.x release so it's still an issue, right?

@cstamas

Copy link
Copy Markdown
Member

Right, 3.x branch has the fix, but 3.6.0 is last release, 3.6.1 yet to happen.

@gsmet

gsmet commented Mar 31, 2026

Copy link
Copy Markdown

@slachiewicz 👋 is there a plan for releasing a 3.x for Maven 3 consumption? Thanks!

@headius

Copy link
Copy Markdown

We have had a request to update the ruby-maven-libs Ruby gem to include this change. ruby-maven-libs is just a container for a complete Maven 3.x distribution, and we would prefer not to have to patch individual elements of that distribution. Therefore we are also interested in this update getting into a Maven 3 release.

@cstamas

Copy link
Copy Markdown
Member

Plexus Utils 3.6.1 w/ fix is released. For Maven 3.9.x it may take some more time. Also, Maven 3.10.x is in preparation (goal is Resolver 2.x shipped with it).

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

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

directory traversal still in org.codehaus.plexus.util.Expand Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")

5 participants

@cstamas@gsmet@headius@slachiewicz
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Fix Zip Slip vulnerability in archive extraction - #296

Merged
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability
Nov 9, 2025
Merged

Fix Zip Slip vulnerability in archive extraction#296
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability

Conversation

CopilotAI commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

Summary

Fixes the Zip Slip vulnerability (arbitrary file write during archive extraction) in the Expand class by improving path validation to prevent directory traversal attacks.

Resolves: https://github.com/codehaus-plexus/plexus-utils/security/code-scanning/1

Problem

The Zip Slip vulnerability is a form of directory traversal attack that allows a malicious zip file to write files outside the intended extraction directory. The original validation in Expand.extractFile() was insufficient:

if (!f.getAbsolutePath().startsWith(dir.getAbsolutePath())) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}

This check had two critical flaws:

  1. Used absolute paths instead of canonical paths: Didn't account for symbolic links or path normalization
  2. Vulnerable to prefix matching: A malicious entry could write to /tmp/extract-evil/malicious.txt when extracting to /tmp/extract because the absolute path string starts with the target directory prefix

Solution

The fix uses canonical paths and adds a file separator to the directory path check to prevent prefix matching attacks:

try {
StringcanonicalDirPath = dir.getCanonicalPath();
StringcanonicalFilePath = f.getCanonicalPath();
// Ensure the file is within the target directory// We need to check that the canonical file path starts with the canonical directory path// followed by a file separator to prevent path traversal attacksif (!canonicalFilePath.startsWith(canonicalDirPath + File.separator)
&& !canonicalFilePath.equals(canonicalDirPath)) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}
} catch (IOExceptione) {
thrownewIOException("Failed to verify entry path for '" + entryName + "'", e);
}

Test Coverage

Added comprehensive test cases in ExpandTest.java:

  • Parent directory traversal attacks (../../evil.txt)
  • Absolute path attacks
  • Prefix matching attacks (extracting to similarly-named directories)
  • Regression test for normal zip extraction

Verification

  • ✅ All 249 tests pass (4 new + 245 existing)
  • ✅ CodeQL security scan confirms 0 vulnerabilities
  • ✅ Code formatting and build checks pass
  • ✅ No breaking changes to existing functionality

The fix is minimal and surgical, changing only 13 lines in the security-critical path validation logic.

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")</issue_title>
<issue_description>

Tracking issue for:

Comments on the Issue (you are @copilot in this section)

Fixes#248


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

CopilotAIand others added 2 commits October 10, 2025 20:39
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix code scanning alert for Zip Slip vulnerabilityFix Zip Slip vulnerability in archive extractionOct 10, 2025
CopilotAI requested a review from slachiewiczOctober 10, 2025 20:46
@slachiewicz
slachiewicz marked this pull request as ready for review October 11, 2025 08:49
@slachiewiczslachiewicz added the bug Something isn't working label Nov 9, 2025
@slachiewicz
slachiewicz merged commit 6d780b3 into masterNov 9, 2025
17 checks passed
@slachiewicz
slachiewicz deleted the copilot/fix-zip-slip-vulnerability branch November 9, 2025 11:32
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
@cstamas

Copy link
Copy Markdown
Member

Can we have this backported to 3.x line as well?

@cstamas

Copy link
Copy Markdown
Member

NVM, missed it is already backported to 3.x

@gsmet

Copy link
Copy Markdown

@cstamas it has been backported but I don't see a 3.x release so it's still an issue, right?

@cstamas

Copy link
Copy Markdown
Member

Right, 3.x branch has the fix, but 3.6.0 is last release, 3.6.1 yet to happen.

@gsmet

gsmet commented Mar 31, 2026

Copy link
Copy Markdown

@slachiewicz 👋 is there a plan for releasing a 3.x for Maven 3 consumption? Thanks!

@headius

Copy link
Copy Markdown

We have had a request to update the ruby-maven-libs Ruby gem to include this change. ruby-maven-libs is just a container for a complete Maven 3.x distribution, and we would prefer not to have to patch individual elements of that distribution. Therefore we are also interested in this update getting into a Maven 3 release.

@cstamas

Copy link
Copy Markdown
Member

Plexus Utils 3.6.1 w/ fix is released. For Maven 3.9.x it may take some more time. Also, Maven 3.10.x is in preparation (goal is Resolver 2.x shipped with it).

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

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

directory traversal still in org.codehaus.plexus.util.Expand Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")

5 participants

@cstamas@gsmet@headius@slachiewicz
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix Zip Slip vulnerability in archive extraction - #296

Merged
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability
Nov 9, 2025
Merged

Fix Zip Slip vulnerability in archive extraction#296
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability

Conversation

CopilotAI commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

Summary

Fixes the Zip Slip vulnerability (arbitrary file write during archive extraction) in the Expand class by improving path validation to prevent directory traversal attacks.

Resolves: https://github.com/codehaus-plexus/plexus-utils/security/code-scanning/1

Problem

The Zip Slip vulnerability is a form of directory traversal attack that allows a malicious zip file to write files outside the intended extraction directory. The original validation in Expand.extractFile() was insufficient:

if (!f.getAbsolutePath().startsWith(dir.getAbsolutePath())) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}

This check had two critical flaws:

  1. Used absolute paths instead of canonical paths: Didn't account for symbolic links or path normalization
  2. Vulnerable to prefix matching: A malicious entry could write to /tmp/extract-evil/malicious.txt when extracting to /tmp/extract because the absolute path string starts with the target directory prefix

Solution

The fix uses canonical paths and adds a file separator to the directory path check to prevent prefix matching attacks:

try {
StringcanonicalDirPath = dir.getCanonicalPath();
StringcanonicalFilePath = f.getCanonicalPath();
// Ensure the file is within the target directory// We need to check that the canonical file path starts with the canonical directory path// followed by a file separator to prevent path traversal attacksif (!canonicalFilePath.startsWith(canonicalDirPath + File.separator)
&& !canonicalFilePath.equals(canonicalDirPath)) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}
} catch (IOExceptione) {
thrownewIOException("Failed to verify entry path for '" + entryName + "'", e);
}

Test Coverage

Added comprehensive test cases in ExpandTest.java:

  • Parent directory traversal attacks (../../evil.txt)
  • Absolute path attacks
  • Prefix matching attacks (extracting to similarly-named directories)
  • Regression test for normal zip extraction

Verification

  • ✅ All 249 tests pass (4 new + 245 existing)
  • ✅ CodeQL security scan confirms 0 vulnerabilities
  • ✅ Code formatting and build checks pass
  • ✅ No breaking changes to existing functionality

The fix is minimal and surgical, changing only 13 lines in the security-critical path validation logic.

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")</issue_title>
<issue_description>

Tracking issue for:

Comments on the Issue (you are @copilot in this section)

Fixes#248


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

CopilotAIand others added 2 commits October 10, 2025 20:39
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix code scanning alert for Zip Slip vulnerabilityFix Zip Slip vulnerability in archive extractionOct 10, 2025
CopilotAI requested a review from slachiewiczOctober 10, 2025 20:46
@slachiewicz
slachiewicz marked this pull request as ready for review October 11, 2025 08:49
@slachiewiczslachiewicz added the bug Something isn't working label Nov 9, 2025
@slachiewicz
slachiewicz merged commit 6d780b3 into masterNov 9, 2025
17 checks passed
@slachiewicz
slachiewicz deleted the copilot/fix-zip-slip-vulnerability branch November 9, 2025 11:32
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
@cstamas

Copy link
Copy Markdown
Member

Can we have this backported to 3.x line as well?

@cstamas

Copy link
Copy Markdown
Member

NVM, missed it is already backported to 3.x

@gsmet

Copy link
Copy Markdown

@cstamas it has been backported but I don't see a 3.x release so it's still an issue, right?

@cstamas

Copy link
Copy Markdown
Member

Right, 3.x branch has the fix, but 3.6.0 is last release, 3.6.1 yet to happen.

@gsmet

gsmet commented Mar 31, 2026

Copy link
Copy Markdown

@slachiewicz 👋 is there a plan for releasing a 3.x for Maven 3 consumption? Thanks!

@headius

Copy link
Copy Markdown

We have had a request to update the ruby-maven-libs Ruby gem to include this change. ruby-maven-libs is just a container for a complete Maven 3.x distribution, and we would prefer not to have to patch individual elements of that distribution. Therefore we are also interested in this update getting into a Maven 3 release.

@cstamas

Copy link
Copy Markdown
Member

Plexus Utils 3.6.1 w/ fix is released. For Maven 3.9.x it may take some more time. Also, Maven 3.10.x is in preparation (goal is Resolver 2.x shipped with it).

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

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

directory traversal still in org.codehaus.plexus.util.Expand Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")

5 participants

@cstamas@gsmet@headius@slachiewicz
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix Zip Slip vulnerability in archive extraction - #296

Merged
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability
Nov 9, 2025
Merged

Fix Zip Slip vulnerability in archive extraction#296
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability

Conversation

CopilotAI commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

Summary

Fixes the Zip Slip vulnerability (arbitrary file write during archive extraction) in the Expand class by improving path validation to prevent directory traversal attacks.

Resolves: https://github.com/codehaus-plexus/plexus-utils/security/code-scanning/1

Problem

The Zip Slip vulnerability is a form of directory traversal attack that allows a malicious zip file to write files outside the intended extraction directory. The original validation in Expand.extractFile() was insufficient:

if (!f.getAbsolutePath().startsWith(dir.getAbsolutePath())) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}

This check had two critical flaws:

  1. Used absolute paths instead of canonical paths: Didn't account for symbolic links or path normalization
  2. Vulnerable to prefix matching: A malicious entry could write to /tmp/extract-evil/malicious.txt when extracting to /tmp/extract because the absolute path string starts with the target directory prefix

Solution

The fix uses canonical paths and adds a file separator to the directory path check to prevent prefix matching attacks:

try {
StringcanonicalDirPath = dir.getCanonicalPath();
StringcanonicalFilePath = f.getCanonicalPath();
// Ensure the file is within the target directory// We need to check that the canonical file path starts with the canonical directory path// followed by a file separator to prevent path traversal attacksif (!canonicalFilePath.startsWith(canonicalDirPath + File.separator)
&& !canonicalFilePath.equals(canonicalDirPath)) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}
} catch (IOExceptione) {
thrownewIOException("Failed to verify entry path for '" + entryName + "'", e);
}

Test Coverage

Added comprehensive test cases in ExpandTest.java:

  • Parent directory traversal attacks (../../evil.txt)
  • Absolute path attacks
  • Prefix matching attacks (extracting to similarly-named directories)
  • Regression test for normal zip extraction

Verification

  • ✅ All 249 tests pass (4 new + 245 existing)
  • ✅ CodeQL security scan confirms 0 vulnerabilities
  • ✅ Code formatting and build checks pass
  • ✅ No breaking changes to existing functionality

The fix is minimal and surgical, changing only 13 lines in the security-critical path validation logic.

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")</issue_title>
<issue_description>

Tracking issue for:

Comments on the Issue (you are @copilot in this section)

Fixes#248


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

CopilotAIand others added 2 commits October 10, 2025 20:39
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix code scanning alert for Zip Slip vulnerabilityFix Zip Slip vulnerability in archive extractionOct 10, 2025
CopilotAI requested a review from slachiewiczOctober 10, 2025 20:46
@slachiewicz
slachiewicz marked this pull request as ready for review October 11, 2025 08:49
@slachiewiczslachiewicz added the bug Something isn't working label Nov 9, 2025
@slachiewicz
slachiewicz merged commit 6d780b3 into masterNov 9, 2025
17 checks passed
@slachiewicz
slachiewicz deleted the copilot/fix-zip-slip-vulnerability branch November 9, 2025 11:32
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
@cstamas

Copy link
Copy Markdown
Member

Can we have this backported to 3.x line as well?

@cstamas

Copy link
Copy Markdown
Member

NVM, missed it is already backported to 3.x

@gsmet

Copy link
Copy Markdown

@cstamas it has been backported but I don't see a 3.x release so it's still an issue, right?

@cstamas

Copy link
Copy Markdown
Member

Right, 3.x branch has the fix, but 3.6.0 is last release, 3.6.1 yet to happen.

@gsmet

gsmet commented Mar 31, 2026

Copy link
Copy Markdown

@slachiewicz 👋 is there a plan for releasing a 3.x for Maven 3 consumption? Thanks!

@headius

Copy link
Copy Markdown

We have had a request to update the ruby-maven-libs Ruby gem to include this change. ruby-maven-libs is just a container for a complete Maven 3.x distribution, and we would prefer not to have to patch individual elements of that distribution. Therefore we are also interested in this update getting into a Maven 3 release.

@cstamas

Copy link
Copy Markdown
Member

Plexus Utils 3.6.1 w/ fix is released. For Maven 3.9.x it may take some more time. Also, Maven 3.10.x is in preparation (goal is Resolver 2.x shipped with it).

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

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

directory traversal still in org.codehaus.plexus.util.Expand Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")

5 participants

@cstamas@gsmet@headius@slachiewicz
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Fix Zip Slip vulnerability in archive extraction - #296

Merged
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability
Nov 9, 2025
Merged

Fix Zip Slip vulnerability in archive extraction#296
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability

Conversation

CopilotAI commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

Summary

Fixes the Zip Slip vulnerability (arbitrary file write during archive extraction) in the Expand class by improving path validation to prevent directory traversal attacks.

Resolves: https://github.com/codehaus-plexus/plexus-utils/security/code-scanning/1

Problem

The Zip Slip vulnerability is a form of directory traversal attack that allows a malicious zip file to write files outside the intended extraction directory. The original validation in Expand.extractFile() was insufficient:

if (!f.getAbsolutePath().startsWith(dir.getAbsolutePath())) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}

This check had two critical flaws:

  1. Used absolute paths instead of canonical paths: Didn't account for symbolic links or path normalization
  2. Vulnerable to prefix matching: A malicious entry could write to /tmp/extract-evil/malicious.txt when extracting to /tmp/extract because the absolute path string starts with the target directory prefix

Solution

The fix uses canonical paths and adds a file separator to the directory path check to prevent prefix matching attacks:

try {
StringcanonicalDirPath = dir.getCanonicalPath();
StringcanonicalFilePath = f.getCanonicalPath();
// Ensure the file is within the target directory// We need to check that the canonical file path starts with the canonical directory path// followed by a file separator to prevent path traversal attacksif (!canonicalFilePath.startsWith(canonicalDirPath + File.separator)
&& !canonicalFilePath.equals(canonicalDirPath)) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}
} catch (IOExceptione) {
thrownewIOException("Failed to verify entry path for '" + entryName + "'", e);
}

Test Coverage

Added comprehensive test cases in ExpandTest.java:

  • Parent directory traversal attacks (../../evil.txt)
  • Absolute path attacks
  • Prefix matching attacks (extracting to similarly-named directories)
  • Regression test for normal zip extraction

Verification

  • ✅ All 249 tests pass (4 new + 245 existing)
  • ✅ CodeQL security scan confirms 0 vulnerabilities
  • ✅ Code formatting and build checks pass
  • ✅ No breaking changes to existing functionality

The fix is minimal and surgical, changing only 13 lines in the security-critical path validation logic.

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")</issue_title>
<issue_description>

Tracking issue for:

Comments on the Issue (you are @copilot in this section)

Fixes#248


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

CopilotAIand others added 2 commits October 10, 2025 20:39
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix code scanning alert for Zip Slip vulnerabilityFix Zip Slip vulnerability in archive extractionOct 10, 2025
CopilotAI requested a review from slachiewiczOctober 10, 2025 20:46
@slachiewicz
slachiewicz marked this pull request as ready for review October 11, 2025 08:49
@slachiewiczslachiewicz added the bug Something isn't working label Nov 9, 2025
@slachiewicz
slachiewicz merged commit 6d780b3 into masterNov 9, 2025
17 checks passed
@slachiewicz
slachiewicz deleted the copilot/fix-zip-slip-vulnerability branch November 9, 2025 11:32
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
@cstamas

Copy link
Copy Markdown
Member

Can we have this backported to 3.x line as well?

@cstamas

Copy link
Copy Markdown
Member

NVM, missed it is already backported to 3.x

@gsmet

Copy link
Copy Markdown

@cstamas it has been backported but I don't see a 3.x release so it's still an issue, right?

@cstamas

Copy link
Copy Markdown
Member

Right, 3.x branch has the fix, but 3.6.0 is last release, 3.6.1 yet to happen.

@gsmet

gsmet commented Mar 31, 2026

Copy link
Copy Markdown

@slachiewicz 👋 is there a plan for releasing a 3.x for Maven 3 consumption? Thanks!

@headius

Copy link
Copy Markdown

We have had a request to update the ruby-maven-libs Ruby gem to include this change. ruby-maven-libs is just a container for a complete Maven 3.x distribution, and we would prefer not to have to patch individual elements of that distribution. Therefore we are also interested in this update getting into a Maven 3 release.

@cstamas

Copy link
Copy Markdown
Member

Plexus Utils 3.6.1 w/ fix is released. For Maven 3.9.x it may take some more time. Also, Maven 3.10.x is in preparation (goal is Resolver 2.x shipped with it).

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

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

directory traversal still in org.codehaus.plexus.util.Expand Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")

5 participants

@cstamas@gsmet@headius@slachiewicz
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix Zip Slip vulnerability in archive extraction - #296

Merged
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability
Nov 9, 2025
Merged

Fix Zip Slip vulnerability in archive extraction#296
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability

Conversation

CopilotAI commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

Summary

Fixes the Zip Slip vulnerability (arbitrary file write during archive extraction) in the Expand class by improving path validation to prevent directory traversal attacks.

Resolves: https://github.com/codehaus-plexus/plexus-utils/security/code-scanning/1

Problem

The Zip Slip vulnerability is a form of directory traversal attack that allows a malicious zip file to write files outside the intended extraction directory. The original validation in Expand.extractFile() was insufficient:

if (!f.getAbsolutePath().startsWith(dir.getAbsolutePath())) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}

This check had two critical flaws:

  1. Used absolute paths instead of canonical paths: Didn't account for symbolic links or path normalization
  2. Vulnerable to prefix matching: A malicious entry could write to /tmp/extract-evil/malicious.txt when extracting to /tmp/extract because the absolute path string starts with the target directory prefix

Solution

The fix uses canonical paths and adds a file separator to the directory path check to prevent prefix matching attacks:

try {
StringcanonicalDirPath = dir.getCanonicalPath();
StringcanonicalFilePath = f.getCanonicalPath();
// Ensure the file is within the target directory// We need to check that the canonical file path starts with the canonical directory path// followed by a file separator to prevent path traversal attacksif (!canonicalFilePath.startsWith(canonicalDirPath + File.separator)
&& !canonicalFilePath.equals(canonicalDirPath)) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}
} catch (IOExceptione) {
thrownewIOException("Failed to verify entry path for '" + entryName + "'", e);
}

Test Coverage

Added comprehensive test cases in ExpandTest.java:

  • Parent directory traversal attacks (../../evil.txt)
  • Absolute path attacks
  • Prefix matching attacks (extracting to similarly-named directories)
  • Regression test for normal zip extraction

Verification

  • ✅ All 249 tests pass (4 new + 245 existing)
  • ✅ CodeQL security scan confirms 0 vulnerabilities
  • ✅ Code formatting and build checks pass
  • ✅ No breaking changes to existing functionality

The fix is minimal and surgical, changing only 13 lines in the security-critical path validation logic.

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")</issue_title>
<issue_description>

Tracking issue for:

Comments on the Issue (you are @copilot in this section)

Fixes#248


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

CopilotAIand others added 2 commits October 10, 2025 20:39
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix code scanning alert for Zip Slip vulnerabilityFix Zip Slip vulnerability in archive extractionOct 10, 2025
CopilotAI requested a review from slachiewiczOctober 10, 2025 20:46
@slachiewicz
slachiewicz marked this pull request as ready for review October 11, 2025 08:49
@slachiewiczslachiewicz added the bug Something isn't working label Nov 9, 2025
@slachiewicz
slachiewicz merged commit 6d780b3 into masterNov 9, 2025
17 checks passed
@slachiewicz
slachiewicz deleted the copilot/fix-zip-slip-vulnerability branch November 9, 2025 11:32
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
@cstamas

Copy link
Copy Markdown
Member

Can we have this backported to 3.x line as well?

@cstamas

Copy link
Copy Markdown
Member

NVM, missed it is already backported to 3.x

@gsmet

Copy link
Copy Markdown

@cstamas it has been backported but I don't see a 3.x release so it's still an issue, right?

@cstamas

Copy link
Copy Markdown
Member

Right, 3.x branch has the fix, but 3.6.0 is last release, 3.6.1 yet to happen.

@gsmet

gsmet commented Mar 31, 2026

Copy link
Copy Markdown

@slachiewicz 👋 is there a plan for releasing a 3.x for Maven 3 consumption? Thanks!

@headius

Copy link
Copy Markdown

We have had a request to update the ruby-maven-libs Ruby gem to include this change. ruby-maven-libs is just a container for a complete Maven 3.x distribution, and we would prefer not to have to patch individual elements of that distribution. Therefore we are also interested in this update getting into a Maven 3 release.

@cstamas

Copy link
Copy Markdown
Member

Plexus Utils 3.6.1 w/ fix is released. For Maven 3.9.x it may take some more time. Also, Maven 3.10.x is in preparation (goal is Resolver 2.x shipped with it).

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

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

directory traversal still in org.codehaus.plexus.util.Expand Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")

5 participants

@cstamas@gsmet@headius@slachiewicz
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix Zip Slip vulnerability in archive extraction - #296

Merged
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability
Nov 9, 2025
Merged

Fix Zip Slip vulnerability in archive extraction#296
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability

Conversation

CopilotAI commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

Summary

Fixes the Zip Slip vulnerability (arbitrary file write during archive extraction) in the Expand class by improving path validation to prevent directory traversal attacks.

Resolves: https://github.com/codehaus-plexus/plexus-utils/security/code-scanning/1

Problem

The Zip Slip vulnerability is a form of directory traversal attack that allows a malicious zip file to write files outside the intended extraction directory. The original validation in Expand.extractFile() was insufficient:

if (!f.getAbsolutePath().startsWith(dir.getAbsolutePath())) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}

This check had two critical flaws:

  1. Used absolute paths instead of canonical paths: Didn't account for symbolic links or path normalization
  2. Vulnerable to prefix matching: A malicious entry could write to /tmp/extract-evil/malicious.txt when extracting to /tmp/extract because the absolute path string starts with the target directory prefix

Solution

The fix uses canonical paths and adds a file separator to the directory path check to prevent prefix matching attacks:

try {
StringcanonicalDirPath = dir.getCanonicalPath();
StringcanonicalFilePath = f.getCanonicalPath();
// Ensure the file is within the target directory// We need to check that the canonical file path starts with the canonical directory path// followed by a file separator to prevent path traversal attacksif (!canonicalFilePath.startsWith(canonicalDirPath + File.separator)
&& !canonicalFilePath.equals(canonicalDirPath)) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}
} catch (IOExceptione) {
thrownewIOException("Failed to verify entry path for '" + entryName + "'", e);
}

Test Coverage

Added comprehensive test cases in ExpandTest.java:

  • Parent directory traversal attacks (../../evil.txt)
  • Absolute path attacks
  • Prefix matching attacks (extracting to similarly-named directories)
  • Regression test for normal zip extraction

Verification

  • ✅ All 249 tests pass (4 new + 245 existing)
  • ✅ CodeQL security scan confirms 0 vulnerabilities
  • ✅ Code formatting and build checks pass
  • ✅ No breaking changes to existing functionality

The fix is minimal and surgical, changing only 13 lines in the security-critical path validation logic.

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")</issue_title>
<issue_description>

Tracking issue for:

Comments on the Issue (you are @copilot in this section)

Fixes#248


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

CopilotAIand others added 2 commits October 10, 2025 20:39
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix code scanning alert for Zip Slip vulnerabilityFix Zip Slip vulnerability in archive extractionOct 10, 2025
CopilotAI requested a review from slachiewiczOctober 10, 2025 20:46
@slachiewicz
slachiewicz marked this pull request as ready for review October 11, 2025 08:49
@slachiewiczslachiewicz added the bug Something isn't working label Nov 9, 2025
@slachiewicz
slachiewicz merged commit 6d780b3 into masterNov 9, 2025
17 checks passed
@slachiewicz
slachiewicz deleted the copilot/fix-zip-slip-vulnerability branch November 9, 2025 11:32
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
@cstamas

Copy link
Copy Markdown
Member

Can we have this backported to 3.x line as well?

@cstamas

Copy link
Copy Markdown
Member

NVM, missed it is already backported to 3.x

@gsmet

Copy link
Copy Markdown

@cstamas it has been backported but I don't see a 3.x release so it's still an issue, right?

@cstamas

Copy link
Copy Markdown
Member

Right, 3.x branch has the fix, but 3.6.0 is last release, 3.6.1 yet to happen.

@gsmet

gsmet commented Mar 31, 2026

Copy link
Copy Markdown

@slachiewicz 👋 is there a plan for releasing a 3.x for Maven 3 consumption? Thanks!

@headius

Copy link
Copy Markdown

We have had a request to update the ruby-maven-libs Ruby gem to include this change. ruby-maven-libs is just a container for a complete Maven 3.x distribution, and we would prefer not to have to patch individual elements of that distribution. Therefore we are also interested in this update getting into a Maven 3 release.

@cstamas

Copy link
Copy Markdown
Member

Plexus Utils 3.6.1 w/ fix is released. For Maven 3.9.x it may take some more time. Also, Maven 3.10.x is in preparation (goal is Resolver 2.x shipped with it).

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

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

directory traversal still in org.codehaus.plexus.util.Expand Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")

5 participants

@cstamas@gsmet@headius@slachiewicz
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Fix Zip Slip vulnerability in archive extraction - #296

Merged
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability
Nov 9, 2025
Merged

Fix Zip Slip vulnerability in archive extraction#296
slachiewicz merged 3 commits into
masterfrom
copilot/fix-zip-slip-vulnerability

Conversation

CopilotAI commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

Summary

Fixes the Zip Slip vulnerability (arbitrary file write during archive extraction) in the Expand class by improving path validation to prevent directory traversal attacks.

Resolves: https://github.com/codehaus-plexus/plexus-utils/security/code-scanning/1

Problem

The Zip Slip vulnerability is a form of directory traversal attack that allows a malicious zip file to write files outside the intended extraction directory. The original validation in Expand.extractFile() was insufficient:

if (!f.getAbsolutePath().startsWith(dir.getAbsolutePath())) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}

This check had two critical flaws:

  1. Used absolute paths instead of canonical paths: Didn't account for symbolic links or path normalization
  2. Vulnerable to prefix matching: A malicious entry could write to /tmp/extract-evil/malicious.txt when extracting to /tmp/extract because the absolute path string starts with the target directory prefix

Solution

The fix uses canonical paths and adds a file separator to the directory path check to prevent prefix matching attacks:

try {
StringcanonicalDirPath = dir.getCanonicalPath();
StringcanonicalFilePath = f.getCanonicalPath();
// Ensure the file is within the target directory// We need to check that the canonical file path starts with the canonical directory path// followed by a file separator to prevent path traversal attacksif (!canonicalFilePath.startsWith(canonicalDirPath + File.separator)
&& !canonicalFilePath.equals(canonicalDirPath)) {
thrownewIOException("Entry '" + entryName + "' outside the target directory.");
}
} catch (IOExceptione) {
thrownewIOException("Failed to verify entry path for '" + entryName + "'", e);
}

Test Coverage

Added comprehensive test cases in ExpandTest.java:

  • Parent directory traversal attacks (../../evil.txt)
  • Absolute path attacks
  • Prefix matching attacks (extracting to similarly-named directories)
  • Regression test for normal zip extraction

Verification

  • ✅ All 249 tests pass (4 new + 245 existing)
  • ✅ CodeQL security scan confirms 0 vulnerabilities
  • ✅ Code formatting and build checks pass
  • ✅ No breaking changes to existing functionality

The fix is minimal and surgical, changing only 13 lines in the security-critical path validation logic.

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")</issue_title>
<issue_description>

Tracking issue for:

Comments on the Issue (you are @copilot in this section)

Fixes#248


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

CopilotAIand others added 2 commits October 10, 2025 20:39
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix code scanning alert for Zip Slip vulnerabilityFix Zip Slip vulnerability in archive extractionOct 10, 2025
CopilotAI requested a review from slachiewiczOctober 10, 2025 20:46
@slachiewicz
slachiewicz marked this pull request as ready for review October 11, 2025 08:49
@slachiewiczslachiewicz added the bug Something isn't working label Nov 9, 2025
@slachiewicz
slachiewicz merged commit 6d780b3 into masterNov 9, 2025
17 checks passed
@slachiewicz
slachiewicz deleted the copilot/fix-zip-slip-vulnerability branch November 9, 2025 11:32
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
slachiewicz pushed a commit that referenced this pull request Nov 9, 2025
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
(cherry picked from commit 6d780b3)
@cstamas

Copy link
Copy Markdown
Member

Can we have this backported to 3.x line as well?

@cstamas

Copy link
Copy Markdown
Member

NVM, missed it is already backported to 3.x

@gsmet

Copy link
Copy Markdown

@cstamas it has been backported but I don't see a 3.x release so it's still an issue, right?

@cstamas

Copy link
Copy Markdown
Member

Right, 3.x branch has the fix, but 3.6.0 is last release, 3.6.1 yet to happen.

@gsmet

gsmet commented Mar 31, 2026

Copy link
Copy Markdown

@slachiewicz 👋 is there a plan for releasing a 3.x for Maven 3 consumption? Thanks!

@headius

Copy link
Copy Markdown

We have had a request to update the ruby-maven-libs Ruby gem to include this change. ruby-maven-libs is just a container for a complete Maven 3.x distribution, and we would prefer not to have to patch individual elements of that distribution. Therefore we are also interested in this update getting into a Maven 3 release.

@cstamas

Copy link
Copy Markdown
Member

Plexus Utils 3.6.1 w/ fix is released. For Maven 3.9.x it may take some more time. Also, Maven 3.10.x is in preparation (goal is Resolver 2.x shipped with it).

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

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

directory traversal still in org.codehaus.plexus.util.Expand Fix code scanning alert - Arbitrary file write during archive extraction ("Zip Slip")

5 participants

@cstamas@gsmet@headius@slachiewicz