fix: TAR quota bypass via PAX-overridden size (issue #82)#85
Merged
Conversation
…ypass header().size() returns the raw ustar value, which is 0 when the actual size is carried in a PAX extended header. entry.size() returns fields.size, which tar-rs sets to the PAX-overridden value before constructing the entry. Using header().size() allowed a crafted TAR (PAX size=N, ustar size=0) to bypass both max_file_size and max_total_size quota checks while writing N bytes to disk. Fix both affected sites in TarEntryAdapter: - extract_file: Some(entry.size()) instead of entry.header().size().ok() - get_uncompressed_size: return u64 directly via entry.size() Adds two regression tests that craft a raw PAX TAR archive and assert extraction is rejected under quota limits. Closes #82
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
entry.header().size()(raw ustar value) withentry.size()(PAX-aware) in quota enforcementTarEntryAdapter:extract_fileandget_uncompressed_sizeRoot cause
header().size()returns the raw octal ustar field, which is 0 when the actual size is stored in a PAX extended header.entry.size()returnsfields.size, which tar-rs sets to the PAX value before constructing the entry. A crafted TAR with PAX size=N and ustar size=0 bypassed bothmax_file_sizeandmax_total_sizechecks while writing N bytes to disk.Security impact
With default config (
max_file_size=50MB,max_total_size=10GB) an attacker could cause disk exhaustion via a TAR archive using PAX extended headers for file size.Test plan
test_pax_size_override_bypasses_max_file_size_quota— PAX 2MB file, limit 1MBtest_pax_size_override_bypasses_max_total_size_quota— PAX 600KB file, total limit 500KBcargo deny checkcleanCloses #82