Skip to content

Commit bce9a49

Browse files
Merge branch 'Chathula-fix-nest-common-mime-validator' into 10.4.15
2 parents d0fb875 + 2b9e132 commit bce9a49

File tree

11 files changed

+29414
-18651
lines changed

11 files changed

+29414
-18651
lines changed

package-lock.json

+29,150-18,607
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"express": "4.21.2",
6767
"fast-json-stringify": "6.0.0",
6868
"fast-safe-stringify": "2.1.1",
69+
"file-type": "20.4.1",
6970
"iterare": "1.2.1",
7071
"object-hash": "3.0.0",
7172
"path-to-regexp": "3.3.0",
@@ -74,7 +75,7 @@
7475
"socket.io": "4.8.1",
7576
"tslib": "2.8.1",
7677
"uid": "2.0.2",
77-
"uuid": "11.0.3"
78+
"uuid": "11.1.0"
7879
},
7980
"devDependencies": {
8081
"@apollo/server": "4.11.2",

packages/common/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"peerDependencies": {
2626
"class-transformer": "*",
2727
"class-validator": "*",
28+
"file-type": "^20.4.1",
2829
"reflect-metadata": "^0.1.12 || ^0.2.0",
2930
"rxjs": "^7.1.0"
3031
},
@@ -34,6 +35,9 @@
3435
},
3536
"class-transformer": {
3637
"optional": true
38+
},
39+
"file-type": {
40+
"optional": true
3741
}
3842
}
3943
}

packages/common/pipes/file/file-type.validator.ts

+40-12
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@ import { IFile } from './interfaces';
33

44
export type FileTypeValidatorOptions = {
55
fileType: string | RegExp;
6+
7+
/**
8+
* If `true`, the validator will skip the magic numbers validation.
9+
* This can be useful when you can't identify some files as there are no common magic numbers available for some file types.
10+
* @default false
11+
*/
12+
skipMagicNumbersValidation?: boolean;
613
};
714

815
/**
9-
* Defines the built-in FileType File Validator. It validates incoming files mime-type
10-
* matching a string or a regular expression. Note that this validator uses a naive strategy
11-
* to check the mime-type and could be fooled if the client provided a file with renamed extension.
12-
* (for instance, renaming a 'malicious.bat' to 'malicious.jpeg'). To handle such security issues
13-
* with more reliability, consider checking against the file's [magic-numbers](https://en.wikipedia.org/wiki/Magic_number_%28programming%29)
16+
* Defines the built-in FileTypeValidator. It validates incoming files by examining
17+
* their magic numbers using the file-type package, providing more reliable file type validation
18+
* than just checking the mimetype string.
1419
*
1520
* @see [File Validators](https://docs.nestjs.com/techniques/file-upload#validators)
1621
*
@@ -20,19 +25,42 @@ export class FileTypeValidator extends FileValidator<
2025
FileTypeValidatorOptions,
2126
IFile
2227
> {
23-
buildErrorMessage(): string {
28+
buildErrorMessage(file?: IFile): string {
29+
if (file?.mimetype) {
30+
return `Validation failed (current file type is ${file.mimetype}, expected type is ${this.validationOptions.fileType})`;
31+
}
2432
return `Validation failed (expected type is ${this.validationOptions.fileType})`;
2533
}
2634

27-
isValid(file?: IFile): boolean {
35+
async isValid(file?: IFile): Promise<boolean> {
2836
if (!this.validationOptions) {
2937
return true;
3038
}
3139

32-
return (
33-
!!file &&
34-
'mimetype' in file &&
35-
!!file.mimetype.match(this.validationOptions.fileType)
36-
);
40+
const isFileValid = !!file && 'mimetype' in file;
41+
42+
if (this.validationOptions.skipMagicNumbersValidation) {
43+
return (
44+
isFileValid && !!file.mimetype.match(this.validationOptions.fileType)
45+
);
46+
}
47+
48+
if (!isFileValid || !file.buffer) {
49+
return false;
50+
}
51+
52+
try {
53+
const { fileTypeFromBuffer } = (await eval(
54+
'import ("file-type")',
55+
)) as typeof import('file-type');
56+
57+
const fileType = await fileTypeFromBuffer(file.buffer);
58+
59+
return (
60+
!!fileType && !!fileType.mime.match(this.validationOptions.fileType)
61+
);
62+
} catch {
63+
return false;
64+
}
3765
}
3866
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export interface IFile {
22
mimetype: string;
33
size: number;
4+
buffer?: Buffer;
45
}

0 commit comments

Comments
 (0)