fix(weixin): confirm the WEBP signature, not just the RIFF prefix (#5285)

detectImageMime treated any data starting with the four RIFF bytes as
image/webp, but RIFF is a generic container also used by WAV and AVI. A
non-WebP RIFF file (e.g. a WAV renamed to .webp) therefore passed the
magic-byte check in validateImagePath, which exists to confirm a file's real
type. Verify the 'WEBP' marker at bytes 8-11 as well, matching the stricter
check already in core's imageTokenizer and the earlier full-signature PNG fix.
This commit is contained in:
Yufeng He 2026-06-19 04:23:38 +08:00 committed by GitHub
parent 5a73dcfc84
commit 5a84ba016b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 41 additions and 3 deletions

View file

@ -162,11 +162,43 @@ describe('detectImageMime', () => {
expect(detectImageMime(buf)).toBe('image/gif');
});
it('detects WebP magic bytes (RIFF)', () => {
const buf = Buffer.from([0x52, 0x49, 0x46, 0x46]);
it('detects WebP magic bytes (RIFF....WEBP)', () => {
const buf = Buffer.from([
0x52,
0x49,
0x46,
0x46, // "RIFF"
0x1a,
0x00,
0x00,
0x00, // file size (little-endian)
0x57,
0x45,
0x42,
0x50, // "WEBP"
]);
expect(detectImageMime(buf)).toBe('image/webp');
});
it('does not misidentify a non-WebP RIFF container (e.g. WAV) as WebP', () => {
// WAV is also a RIFF container; only bytes 8-11 distinguish it from WebP.
const buf = Buffer.from([
0x52,
0x49,
0x46,
0x46, // "RIFF"
0x24,
0x00,
0x00,
0x00, // file size
0x57,
0x41,
0x56,
0x45, // "WAVE", not "WEBP"
]);
expect(() => detectImageMime(buf)).toThrow('Unrecognized image format');
});
it('detects JPEG magic bytes', () => {
const buf = Buffer.from([0xff, 0xd8, 0xff]);
expect(detectImageMime(buf)).toBe('image/jpeg');

View file

@ -90,11 +90,17 @@ export function detectImageMime(data: Buffer): string {
if (data[0] === 0x47 && data[1] === 0x49 && data[2] === 0x46) {
return 'image/gif';
}
// WebP is a RIFF container, so the "RIFF" prefix alone is not enough — WAV and
// AVI share it. The bytes at offset 8-11 must spell "WEBP" to confirm the type.
if (
data[0] === 0x52 &&
data[1] === 0x49 &&
data[2] === 0x46 &&
data[3] === 0x46
data[3] === 0x46 &&
data[8] === 0x57 &&
data[9] === 0x45 &&
data[10] === 0x42 &&
data[11] === 0x50
) {
return 'image/webp';
}