Skip to content

feat: add zip extraction support#5746

Open
ArielLeyva wants to merge 5 commits intofilebrowser:masterfrom
ArielLeyva:feat/5723-can-unzip-a-file
Open

feat: add zip extraction support#5746
ArielLeyva wants to merge 5 commits intofilebrowser:masterfrom
ArielLeyva:feat/5723-can-unzip-a-file

Conversation

@ArielLeyva
Copy link
Copy Markdown
Contributor

@ArielLeyva ArielLeyva commented Feb 6, 2026

Description

This PR introduces a secure and configurable unzip handler to FileBrowser. It adds server‑level configuration options with sensible defaults and enforces multiple safety checks to prevent ZIP bombs, path traversal, and denial‑of‑service scenarios.
The zip file extraction function is disabled by default and can be enabled by using the --unzipEnabled flag or by enabling it through filebrowser config set.

Key changes

  1. New server configuration fields with defaults:
  • MaxZipFileSize (default: 5GB): Maximum size of zip files that can be extracted (large files may cause DoS attacks).
  • MaxZipFileEntries (default: 100k files): Maximum number of files in the zip archive (zip archives with too many files can trigger DoS attacks).
  • MaxTotalUncompressedSize (default: 20GB): This is the disk space that the file will occupy once it is fully decompressed (a necessary check to avoid completely filling up the available disk space and crashing the system).
  • MaxUncompressedSizeRate (default: 0.01 → 1%): The ratio between the size of each compressed and uncompressed file (prevents zip bomb attacks). Some malicious files (zip bombs) can "lie" about their uncompressed size, so every time a file is extracted from the zip archive, it is checked that the size it occupies on the disk matches the size declared in the zip file (if they don't match, the zip file "lies" and the extraction is stopped immediately because it is considered a corrupt or malicious file).
  • MaxUncompressedFileSize (default: 5GB): Maximum size that each uncompressed file can occupy (avoids using up all available disk space and crashing the system).
  1. Unzip handler implementation:
  • Validates permissions and destination paths.
  • Prevents Zip Slip attacks by sanitizing and rejecting absolute/relative escape paths.
  • Enforces limits on compressed size, uncompressed size, number of entries, and compression ratio.
  • Uses io.LimitReader to guard against infinite streams and oversized files.
  • Provides clear error handling with user feedback.
  1. Defaults integrated into server initialization so they can be overridden via configuration.
  • In other words, in older instances of filebrowser configurations where newer configurations do not exist, default values ​​are used to avoid incompatibilities with databases or configuration files from previous versions.

Additional Information

Extracting compressed files is a highly requested feature in the project, and an optional, clear, and secure implementation is necessary for some users.

Checklist

Before submitting your PR, please indicate which issues are either fixed or closed by this PR. See GitHub Help: Closing issues using keywords.

  • I am aware the project is currently in maintenance-only mode. See README
  • I am aware that translations MUST be made through Transifex and that this PR is NOT a translation update
  • I am making a PR against the master branch.
  • I am sure File Browser can be successfully built. See builds and development.

@ArielLeyva ArielLeyva requested a review from a team as a code owner February 6, 2026 04:38
@hacdias
Copy link
Copy Markdown
Member

hacdias commented Feb 8, 2026

Extracting compressed files is a highly requested feature in the project

Could you send me some examples?

@ArielLeyva
Copy link
Copy Markdown
Contributor Author

Extracting compressed files is a highly requested feature in the project

Could you send me some examples?

These issues discuss this function (#5723, #3210, #2768, #2316, #1541, and #3529).

I know that a partial solution has been found using "command execution," but its use hasn't been very clear and is somewhat risky. The idea I propose with this pull request is a decompression tool handled directly by Go, making it a bit safer and allowing this function to be readily available from the Filebrowser interface.

Comment thread settings/settings.go
ImageResolutionCal bool `json:"imageResolutionCalculation"`
AuthHook string `json:"authHook"`
TokenExpirationTime string `json:"tokenExpirationTime"`
UnzipEnabled bool `json:"unzipEnabled"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For consistency with other settings:

Suggested change
UnzipEnabled bool `json:"unzipEnabled"`
UnzipEnabled bool `json:"enableUnzip"`

Comment thread cmd/root.go
flags.Bool("disableExec", true, "disables Command Runner feature")
flags.Bool("disableTypeDetectionByHeader", false, "disables type detection by reading file headers")
flags.Bool("disableImageResolutionCalc", false, "disables image resolution calculation by reading image files")
flags.Bool("unzipEnabled", false, "enable zip file extraction")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All other flags are --disable{Functionality}. I'd rather stay consistent here, unless there's a good reason not to.

Copy link
Copy Markdown
Contributor Author

@ArielLeyva ArielLeyva Feb 15, 2026

Choose a reason for hiding this comment

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

Oh right, I know it doesn't really follow the structure that has been used so far in the project; I would like to be able to implement it as you suggest. I did it the other way around because I didn't want to 'affect' users who were already running filebrowser and might not want this zip extraction feature for security reasons, but I don't think it will bother them. In the way you mention, if a user doesn't want this functionality, they can disable it with the flag --disable{Functionality}. If you tell me that the --disable{Functionality} approach is correct for the project, I will do it that way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm... you do have a point. The only disable that is on by default is --disableExec, so that could be technically done.

However, making it --disableX would not affect existing installations I think. Because the --disable flag is an override. The default setting for new users would be True, but for existing users, the new field in the settings would still be False.

I think if we go with that approach, it'd work and be consistent. Other features have been added with time, making them enabled by default for new installations only.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants