Repository navigation
Bound every size-driven read when opening EWF images - #14
Merged
Merged
Conversation
Locks in the Host, Origin and Sec-Fetch-Site checks that keep other origins and DNS-rebinding pages from driving the local interface. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Synthetic images are built in code (tests/imagebuild_*.py) so no evidence or binary fixture is committed. Ten engine bugs found along the way are recorded as expected failures, each naming the fault: inline data and inline directories, sparse extents, extent-tree blow-up, the deleted-file path without a journal, short and truncated hives, over-broad EWF segment discovery, truncated zlib chunks, and split raw sets. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Volumes are built in code (FAT32 sparsely, as it needs ~34 MB) and opened the way the server opens them. Seven engine bugs are recorded as expected failures: scrambled deleted long names and wrong slack for deleted files on FAT; an unbounded contiguous run list, truncated contiguous directories and unconverted UTC offsets on exFAT; invalid MFT records served from the cache, and a record count that ignores volume size when $MFT is unreadable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tests/fuzz.py mutates the synthetic images and drives the app's own entry points in a child worker, so hangs and memory blow-ups are caught and their inputs kept for replay. It runs in its own workflow: briefly and non-blocking on PRs that touch the engine, and at length weekly or on demand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
EwfImage._fh is a method, not a handle, so the harness's cleanup raised on every EWF case and swamped the real findings. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Section sizes, table base offsets, section pointers and chunk geometry all come from the segment file, and were used directly as read lengths and seek offsets. One corrupt descriptor could make Strata try to read gigabytes into memory, or raise OverflowError/OSError instead of reporting the damage. Reads now go through _read_bounded, capped by the end of the segment and by what the format can hold. Metadata sections are capped at 1 MB, headers at 16 MB, table entries at 2^20, and chunks at the declared chunk size plus zlib's worst-case expansion. Implausible sector or chunk sizes fall back to the defaults. Each clip is recorded as a finding rather than dropped. A failed open also closes its segment handles, which would otherwise stay locked on Windows. Found by tests/fuzz.py; the new HostileSizes tests fail on the previous code and every recorded EWF fuzz input now opens or fails cleanly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 16, 2026
Closed
This was referenced Sep 17, 2026
switch-nz
added a commit
to deadp/strata
that referenced
this pull request
Sep 17, 2026
Known issues pointed only at switch-nz#15, which covers crashes and hangs. The bugs that matter more to an examiner reading release notes are the ones that return wrong or missing results with no finding, tracked in switch-nz#19: exFAT timestamps labelled UTC without applying the offset, sparse ext4 files at the wrong offsets, misread ext4 inline data, scrambled deleted FAT names and misplaced FAT slack, a truncated EWF chunk returned short, and split raw sets loading as a partial disk. Each is still an expected failure on main, so each is listed individually rather than behind a link. 0.1.0 is not tagged yet, so what has merged since this changelog was written ships in it: the EWF read bounds (switch-nz#14), the exFAT contiguous run clamp (switch-nz#17) and the parser tests, fuzzing and CodeQL (switch-nz#13) are added. Raw/dd is described as single-file and split raw sets move to Not implemented, matching the README correction in switch-nz#20. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
This branches from #13. Only the last commit (
Bound every size-driven read when opening EWF images) is new. Once #13 merges, this diff shrinks to that commit alone.Problem
EwfImageused sizes and offsets from the segment file directly as read lengths and seek offsets:size(volume, header, hash and digest sections)nextpointersectors_per_chunk × bytes_per_sector, which also sizes the zero-fill for a chunk that won't decompressOne damaged or hostile descriptor could therefore make Strata try to read gigabytes into memory. In other cases it raised
OverflowErrororOSErrorfromseek, instead of recording a finding.tests/fuzz.pyhit all of these within 3 minutes (ewf.py:178, 195, 211, 291, 305, 306, 317).Fix
_read_bounded, which stops at the end of the segment and at a per-structure cap: metadata sections 1 MB, header sections 16 MB, table entries 2^20, chunks at the chunk size plus zlib's worst-case expansion.Readable images behave as before: the existing EWF tests pass unchanged, including the ones asserting no findings on clean images.
Tests
HostileSizesclass intests/test_ewf.pywith 8 tests. All 8 fail or error on the previousewf.pyand pass with this change.EwfError.🤖 Generated with Claude Code