Harden the JPEG EXIF scanner against malformed input #11
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
extractExifFromJpeginsrc/metadata-backup.ts:79-100walks JPEG segment markers usinglength fields taken directly from the file. Two problems:
Buffer.from(buf.buffer, byteOffset + offset + 4, len - 2)is constructed from anunvalidated
len, so a segment length that runs past the end of the buffer throwsRangeError. The outercatchswallows it, so the file silently backs up with no metadataand no indication that the input was malformed.
len === 0makesoffset += 2 + lenadvance by 2 forever, so the scancannot terminate on certain inputs.
The bytes come from decrypted user photos, so the input is not hostile in the normal case —
but a corrupt or truncated original in someone's library should not be able to hang
quak backup-metadata --exif, and a parse failure should be visible rather thanindistinguishable from "this photo has no EXIF".
The same file has four more bare
catch { }blocks (:118-120,:125-128,:147-149,:162-163) that flatten every failure toundefined.Definition of done
before use; an out-of-range length ends the scan cleanly rather than throwing.
lengths. A test proves this with a crafted input.
JSON records that extraction was attempted and failed, with a reason, rather than silently
omitting the field.
catch { }blocks insrc/metadata-backup.tseither record a reason orcarry a comment explaining why swallowing is correct there.
length past end-of-buffer, a valid JPEG with EXIF (unchanged behaviour), and a file that is
not a JPEG at all.
make checkgreen.TODO.mdupdated in the same commit.