Skip to content

Conversation

@ekuboo100
Copy link

@ekuboo100 ekuboo100 commented Dec 20, 2025

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have made corresponding change to the default configuration files
  • I have added tests that prove my fix is effective or that my feature works. Where relevant, I have used the stresstest.sh script to run them under stress conditions and race detector to verify their stability.
  • I have added an entry in ./changelog/fragments using the changelog tool.

Summary

fixes an archive extraction vulnerability in unzip where filesystem paths derived from ZIP archive entries were not consistently validated. Under specific conditions, a crafted archive could exploit directory traversal sequences (e.g. ..) to write files outside the intended extraction directory.

Background / Problem Statement

When extracting ZIP archives, each archive entry contains a file path that is fully controlled by the archive author. These paths are not inherently restricted and may include traversal components such as ../ or platform-specific equivalents. If such paths are used directly to construct filesystem paths, extraction may occur outside the expected destination directory. if a ZIP entry contains the path ..\elastic-pwned and the archive is extracted into C:\output, naïvely joining these paths This behavior can lead to unauthorized file creation or modification outside the extraction root, potentially resulting in sensitive data exposure, file deletion, or unintended behavior changes.

The file already contains a helper function, sanitizeFilePath, which safely constructs and validates extraction paths by:

  • Joining the extraction root (workdir) with the archive entry path
  • Cleaning and resolving the resulting path
  • Ensuring the final path remains within the intended extraction directory

However, this protection is only applied when folder == "".

When folder != "", the destination path is currently computed as:

sansFolder := splitZipFileName[folderDepth:]
destPath = filepath.Join(workdir, filepath.Join(sansFolder...))

In this case, no validation or sanitization is performed after path construction, allowing crafted ZIP entries to bypass the existing safety checks.

Fix Description

This change ensures that all filesystem paths derived from ZIP archive entries are consistently sanitized, regardless of whether a folder prefix is used.

The fix follows a minimal and safe approach:

  • Preserve the existing logic that restricts processing to archive entries whose names start with the expected prefix.
  • After deriving the relative path components (sansFolder), join them into a relative path string.
  • Pass the resulting relative path through sanitizeFilePath, using workdir as the extraction root.
  • Use the sanitized path for all subsequent filesystem operations.
  • Propagate any validation error returned by sanitizeFilePath.

Implementation Details

Specifically, in unzipFile:

  1. Replace the direct filepath.Join(workdir, filepath.Join(sansFolder...)) usage.
  2. Construct a relative path using filepath.Join(sansFolder...).
  3. Call sanitizeFilePath(workdir, relativePath) and assign the returned value to destPath.
  4. Return an error if path sanitization fails.

This ensures that any traversal attempts are reliably detected and blocked before file extraction occurs. By enforcing consistent path validation for all ZIP entries, this change prevents directory traversal during archive extraction and ensures that files cannot be written outside the intended extraction root. This aligns the behavior of all code paths with the existing security expectations already implemented in sanitizeFilePath.

@ekuboo100 ekuboo100 requested review from a team as code owners December 20, 2025 02:10
@ekuboo100 ekuboo100 requested review from belimawr and faec December 20, 2025 02:10
@botelastic botelastic bot added the needs_team Indicates that the issue/PR needs a Team:* label label Dec 20, 2025
@github-actions
Copy link
Contributor

🤖 GitHub comments

Just comment with:

  • run docs-build : Re-trigger the docs validation. (use unformatted text in the comment!)

@mergify
Copy link
Contributor

mergify bot commented Dec 20, 2025

This pull request does not have a backport label.
If this is a bug or security fix, could you label this PR @odaysec? 🙏.
For such, you'll need to label your PR with:

  • The upcoming major version of the Elastic Stack
  • The upcoming minor version of the Elastic Stack (if you're not pushing a breaking change)

To fixup this pull request, you need to add the backport labels for the needed
branches, such as:

  • backport-8./d is the label to automatically backport to the 8./d branch. /d is the digit
  • backport-active-all is the label that automatically backports to all active branches.
  • backport-active-8 is the label that automatically backports to all active minor branches for the 8 major.
  • backport-active-9 is the label that automatically backports to all active minor branches for the 9 major.

@ekuboo100
Copy link
Author

/backport-active-all

@pierrehilbert pierrehilbert added Team:obs-ds-hosted-services Label for the Observability Hosted Services team Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team Team:Security-Service Integrations Security Service Integrations Team labels Dec 21, 2025
@elasticmachine
Copy link
Contributor

Pinging @elastic/obs-ds-hosted-services (Team:obs-ds-hosted-services)

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-service-integrations (Team:Security-Service Integrations)

@elasticmachine
Copy link
Contributor

Pinging @elastic/elastic-agent-data-plane (Team:Elastic-Agent-Data-Plane)

@botelastic botelastic bot removed the needs_team Indicates that the issue/PR needs a Team:* label label Dec 21, 2025
@pierrehilbert pierrehilbert requested review from VihasMakwana and removed request for faec December 21, 2025 07:42
Co-authored-by: Chris Berkhout <chrisberkhout@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team Team:obs-ds-hosted-services Label for the Observability Hosted Services team Team:Security-Service Integrations Security Service Integrations Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants