micro-editor / micro-editor/micro

[BUG] util.Unzip copies archive entries without an output-size limit

Open
#4,161 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug triage
Dominant language
Go
Stars
29.6k
Forks
1.4k
Avg merge
2d 18h
Merged PRs (30d)
10

Description

Description

Description

util.Unzip rejects traversal entries with a destination path boundary check, but it copies each archive entry with io.Copy and does not appear to enforce a per-entry or total output-size limit.

Relevant code in internal/util/util.go:

path := filepath.Join(dest, f.Name)

if !strings.HasPrefix(path, filepath.Clean(dest)+string(os.PathSeparator)) {
    return fmt.Errorf("illegal file path: %s", path)
}

_, err = io.Copy(f, rc)

Local validation output:

=== RUN   TestReproH12_UnzipBombAndTraversalMitigation
    repro_high_test.go:57:   (a) traversal rejected by HasPrefix: illegal file path: /tmp/TestReproH12_UnzipBombAndTraversalMitigation3808501357/outside.txt
    repro_high_test.go:76:   (b) 2182-byte zip -> 2097152 bytes via io.Copy with NO LimitReader
    repro_high_test.go:77: H12 = SPLIT: traversal mitigated (HasPrefix, FP), zip bomb real (io.Copy no cap, TP)
--- PASS: TestReproH12_UnzipBombAndTraversalMitigation (0.01s)

Expected behavior:

Unzip should enforce a reasonable per-entry and/or total extracted-size limit, or allow callers to provide one.

Actual behavior:

Each entry is copied until EOF, so extracted output size is controlled entirely by the archive contents.

Suggested fix:

Add an extraction size budget, such as a maximum bytes-per-entry and total extracted bytes. The copy path could use a bounded reader/writer and return an error once the configured limit is exceeded.

Environment

Environment

  • Version: tested at commit 77de728b87a624f7cfef1a7db79ff383421780fe
  • OS: Linux / Docker
  • Terminal: N/A

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in internal/util/util.go at util.Unzip and review the io.Copy path, then run repro_high_test.go to reproduce the archive expansion case. Add enforced per-entry or total extraction limits and tests showing oversized extraction is rejected while traversal protection still works.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.