fix(asar): path traversal (zip-slip) on extract + Pickle buffer overrun#143
Open
dchukkapalli-dev wants to merge 2 commits into
Open
Conversation
AsarExtractor's path-traversal guard called Extensions.GetRelativePath, whose fast path strips the destination prefix literally without resolving ".." segments. A crafted archive entry such as "a/../../evil" produced a relative path that did not start with "..", so the guard passed and the file was written outside the extraction directory once the OS resolved the "..". The out-of-package symlink guard shared the same weakness. Add Extensions.IsPathInside, which normalises both paths with Path.GetFullPath before the containment check, and use it for both the file/directory and symlink guards. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pickle.Resize allocated the backing array as _header.Length + newCapacity but advertised _capacityAfterHeader = newCapacity. On the first growth _header is still empty, so the array ended up _headerSize (4) bytes short of the header + capacity it claimed. A write that fills the payload then overran the buffer, throwing an ArgumentException when the serialised asar header was 4089-4092 bytes. Allocate _headerSize + newCapacity instead, matching Chromium's realloc(header_size_ + new_capacity). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dchukkapalli-dev
force-pushed
the
fix/asar-extraction-safety-and-process-kill
branch
from
July 13, 2026 20:21
585da71 to
7d28eb7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes two code-level bugs in the
AsarSharppack/extract pipeline found by source audit (full write-ups and reproductions in #142).1.
AsarSharp/AsarExtractor.cs— path traversal / zip-slip (major)The extraction guard used
Extensions.GetRelativePath, whose fast path strips thedestprefix without resolving.., so a crafted entry likea/../../evilbypassed the check and was written outsidedest. The out-of-package symlink guard shared the weakness.Extensions.IsPathInside, which normalises both paths withPath.GetFullPathbefore the containment check.2.
AsarSharp/PickleTools/Pickle.cs— payload buffer overrun (major)Resizeallocated_header.Length + newCapacitybut advertised_capacityAfterHeader = newCapacity, leaving the backing array_headerSize(4) bytes short on the first growth. A serialised asar header of 4089–4092 bytes overran the buffer (ArgumentException) during packing._headerSize + newCapacity, matching Chromium'sPickle::Resize.Changes
AsarSharp/Utils/Extensions.cs— newIsPathInsidehelper (normalising containment check).AsarSharp/AsarExtractor.cs— both traversal guards useIsPathInside.AsarSharp/PickleTools/Pickle.cs— correctedResizeallocation.All changes are minimal and localised; no public API or behaviour change beyond the fixes.
Testing
There is no automated test project for the C# solution and I don't have the WeMod runtime, so I verified by:
a/../../evilescape; the patched logic handles both while leaving every other size and all legitimate paths unchanged.Per
CONTRIBUTING.md, please build the solution in your environment to confirm compilation. Happy to adjust naming/placement (e.g. theIsPathInsidehelper) to fit project conventions.Fixes #142