@@ -4,13 +4,24 @@ const MAGIC_BYTES: Record<string, Buffer[]> = {
44 'image/png' : [ Buffer . from ( [ 0x89 , 0x50 , 0x4e , 0x47 ] ) ] ,
55 'image/jpeg' : [ Buffer . from ( [ 0xff , 0xd8 , 0xff ] ) ] ,
66 'image/gif' : [ Buffer . from ( 'GIF87a' ) , Buffer . from ( 'GIF89a' ) ] ,
7- 'image/webp' : [ Buffer . from ( 'RIFF' ) ] ,
87 'application/pdf' : [ Buffer . from ( '%PDF' ) ] ,
98 'application/zip' : [ Buffer . from ( [ 0x50 , 0x4b , 0x03 , 0x04 ] ) ] ,
109} ;
1110
12- /** MIME types that are verified binary — skip text pattern scanning for these. */
13- const BINARY_MIME_TYPES = new Set ( Object . keys ( MAGIC_BYTES ) ) ;
11+ /**
12+ * RIFF-based formats need extra validation — RIFF is shared by WAV, AVI, WebP, etc.
13+ * WebP files are: RIFF (4 bytes) + file size (4 bytes) + WEBP (4 bytes at offset 8).
14+ */
15+ const RIFF_HEADER = Buffer . from ( [ 0x52 , 0x49 , 0x46 , 0x46 ] ) ; // RIFF
16+ const WEBP_MARKER = Buffer . from ( [ 0x57 , 0x45 , 0x42 , 0x50 ] ) ; // WEBP
17+
18+ function isValidWebP ( fileBuffer : Buffer ) : boolean {
19+ if ( fileBuffer . length < 12 ) return false ;
20+ return (
21+ fileBuffer . subarray ( 0 , 4 ) . equals ( RIFF_HEADER ) &&
22+ fileBuffer . subarray ( 8 , 12 ) . equals ( WEBP_MARKER )
23+ ) ;
24+ }
1425
1526/**
1627 * Patterns that indicate potentially dangerous HTML/script content.
@@ -34,7 +45,17 @@ export function validateFileContent(
3445) : void {
3546 const lowerMime = declaredMimeType . toLowerCase ( ) ;
3647
37- // Check magic bytes for known binary types
48+ // WebP needs special handling — RIFF prefix is shared with WAV, AVI, etc.
49+ if ( lowerMime === 'image/webp' ) {
50+ if ( ! isValidWebP ( fileBuffer ) ) {
51+ throw new BadRequestException (
52+ 'The uploaded file is invalid or corrupted. Please try again with a valid file.' ,
53+ ) ;
54+ }
55+ return ;
56+ }
57+
58+ // Check magic bytes for other known binary types
3859 const expectedSignatures = MAGIC_BYTES [ lowerMime ] ;
3960 if ( expectedSignatures ) {
4061 const matchesSignature = expectedSignatures . some ( ( sig ) =>
@@ -46,7 +67,6 @@ export function validateFileContent(
4667 ) ;
4768 }
4869 // Binary file passed magic byte check — skip text pattern scanning
49- // to avoid false positives from binary data matching text patterns
5070 return ;
5171 }
5272
0 commit comments