Skip to content

fix(common): introduce magic file type validator to nestjs common #14948

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 50 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
3dc367b
fix(common): introduce magic file type validator to nestjs common
Chathula Mar 31, 2025
598ee4f
chore: add file type package to package.json
Chathula Mar 31, 2025
ac04c34
chore: use load-esm to use file type package
Chathula Mar 31, 2025
d7a6952
revert sample file upload changes
Chathula Mar 31, 2025
0ff0558
chore: export magic file type validator
Chathula Mar 31, 2025
4d21f1e
fix: fixed sample typo
Chathula Mar 31, 2025
e1229b1
fix: switch to magic file validator by default
Chathula Mar 31, 2025
fdebabd
chore: update exports in pipe
Chathula Mar 31, 2025
b03302c
chore: update file type import
Chathula Mar 31, 2025
4a2c6e0
fix: rename magic file type validator to file type validator
Chathula Apr 1, 2025
30e4aca
chore: refactor validation code
Chathula Apr 1, 2025
db2fe5b
chore: update validations
Chathula Apr 1, 2025
100d3c0
chore: handles undefined
Chathula Apr 1, 2025
c571796
chore: update import paths
Chathula Apr 1, 2025
dd19ac8
fix: changed file-type import to promise
Chathula Apr 1, 2025
579d68a
refactor: revert import change
Chathula Apr 1, 2025
69fd0e9
refactor(common): removed async keyword
Chathula Apr 4, 2025
010607f
fix(common): used eval import
Chathula Apr 9, 2025
f6f4baf
refactor(common): refactor code to use simple eval
Chathula Apr 9, 2025
18750bd
refactor(common): move file-type package to peer dependencies
Chathula Apr 10, 2025
d51f9b6
refactor(common): move back file type validator options type
Chathula Apr 11, 2025
14c6cd0
Update packages/common/pipes/file/file-type.validator.ts
kamilmysliwiec Apr 11, 2025
315fe55
fix(common): introduce magic file type validator to nestjs common
Chathula Mar 31, 2025
a203e07
chore: add file type package to package.json
Chathula Mar 31, 2025
c6240a0
chore: use load-esm to use file type package
Chathula Mar 31, 2025
7f37b49
revert sample file upload changes
Chathula Mar 31, 2025
ca1bd82
chore: export magic file type validator
Chathula Mar 31, 2025
5feec1f
fix: fixed sample typo
Chathula Mar 31, 2025
0595929
fix: switch to magic file validator by default
Chathula Mar 31, 2025
d57f934
chore: update exports in pipe
Chathula Mar 31, 2025
f37603a
chore: update file type import
Chathula Mar 31, 2025
23308c7
fix: rename magic file type validator to file type validator
Chathula Apr 1, 2025
cda46a2
chore: refactor validation code
Chathula Apr 1, 2025
2260e00
chore: update validations
Chathula Apr 1, 2025
d90cc8d
chore: handles undefined
Chathula Apr 1, 2025
38a77e2
chore: update import paths
Chathula Apr 1, 2025
5ae8168
fix: changed file-type import to promise
Chathula Apr 1, 2025
890fde4
refactor: revert import change
Chathula Apr 1, 2025
cddbcd1
fix(common): update file mime package and add param skip magic numbers
Chathula Apr 4, 2025
08840c5
fix: remove unused e2e test
Chathula Apr 4, 2025
1f20f52
refactor(common): removed async keyword
Chathula Apr 4, 2025
6953b7a
fix(common): used eval import
Chathula Apr 9, 2025
0b7af8a
refactor(common): refactor code to use simple eval
Chathula Apr 9, 2025
07b4b38
refactor(common): move file-type package to peer dependencies
Chathula Apr 10, 2025
a28fc03
refactor(common): move back file type validator options type
Chathula Apr 11, 2025
312a54a
Update packages/common/pipes/file/file-type.validator.ts
kamilmysliwiec Apr 11, 2025
983216b
chore: update package lock
Chathula Apr 11, 2025
0ac7959
chore: minor tweaks
kamilmysliwiec Apr 11, 2025
6196ab2
Merge branch 'Chathula-fix-nestjs-common-mime-validator'
kamilmysliwiec Apr 11, 2025
cb0d650
chore: remove duplicate packages
Chathula Apr 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47,757 changes: 29,150 additions & 18,607 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"express": "4.21.2",
"fast-json-stringify": "6.0.0",
"fast-safe-stringify": "2.1.1",
"file-type": "20.4.1",
"iterare": "1.2.1",
"object-hash": "3.0.0",
"path-to-regexp": "3.3.0",
Expand All @@ -74,7 +75,7 @@
"socket.io": "4.8.1",
"tslib": "2.8.1",
"uid": "2.0.2",
"uuid": "11.0.3"
"uuid": "11.1.0"
},
"devDependencies": {
"@apollo/server": "4.11.2",
Expand Down
1 change: 1 addition & 0 deletions packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"peerDependencies": {
"class-transformer": "*",
"class-validator": "*",
"file-type": "^20.4.1",
"reflect-metadata": "^0.1.12 || ^0.2.0",
"rxjs": "^7.1.0"
},
Expand Down
52 changes: 40 additions & 12 deletions packages/common/pipes/file/file-type.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ import { IFile } from './interfaces';

export type FileTypeValidatorOptions = {
fileType: string | RegExp;

/**
* If `true`, the validator will skip the magic numbers validation.
* This can be useful when you can't identify some files as there are no common magic numbers available for some file types.
* @default false
*/
skipMagicNumbersValidation?: boolean;
};

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

isValid(file?: IFile): boolean {
async isValid(file?: IFile): Promise<boolean> {
if (!this.validationOptions) {
return true;
}

return (
!!file &&
'mimetype' in file &&
!!file.mimetype.match(this.validationOptions.fileType)
);
const isFileValid = !!file && 'mimetype' in file;

if (this.validationOptions.skipMagicNumbersValidation) {
return (
isFileValid && !!file.mimetype.match(this.validationOptions.fileType)
);
}

if (!isFileValid || !file.buffer) {
return false;
}

try {
const { fileTypeFromBuffer } = (await eval(
'import ("file-type")',
)) as typeof import('file-type');

const fileType = await fileTypeFromBuffer(file.buffer);

return (
!!fileType && !!fileType.mime.match(this.validationOptions.fileType)
);
} catch {
return false;
}
}
}
1 change: 1 addition & 0 deletions packages/common/pipes/file/interfaces/file.interface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface IFile {
mimetype: string;
size: number;
buffer?: Buffer;
}
Loading