mirror of
https://github.com/KevinMidboe/immich.git
synced 2025-10-29 17:40:28 +00:00
feat(server): sanitized path for asset creation process to avoid security risk (#717)
* feat(server): sanitized path for asset creation process to avoid security risk * Sanitize resize path
This commit is contained in:
@@ -6,6 +6,7 @@ import { diskStorage } from 'multer';
|
||||
import { extname, join } from 'path';
|
||||
import { Request } from 'express';
|
||||
import { randomUUID } from 'crypto';
|
||||
import sanitize from 'sanitize-filename';
|
||||
|
||||
export const assetUploadOption: MulterOptions = {
|
||||
fileFilter: (req: Request, file: any, cb: any) => {
|
||||
@@ -19,17 +20,13 @@ export const assetUploadOption: MulterOptions = {
|
||||
storage: diskStorage({
|
||||
destination: (req: Request, file: Express.Multer.File, cb: any) => {
|
||||
const basePath = APP_UPLOAD_LOCATION;
|
||||
// TODO these are currently not used. Shall we remove them?
|
||||
// const fileInfo = req.body as CreateAssetDto;
|
||||
|
||||
// const yearInfo = new Date(fileInfo.createdAt).getFullYear();
|
||||
// const monthInfo = new Date(fileInfo.createdAt).getMonth();
|
||||
|
||||
if (!req.user) {
|
||||
return;
|
||||
}
|
||||
|
||||
const originalUploadFolder = join(basePath, req.user.id, 'original', req.body['deviceId']);
|
||||
const sanitizedDeviceId = sanitize(req.body['deviceId']);
|
||||
const originalUploadFolder = join(basePath, req.user.id, 'original', sanitizedDeviceId);
|
||||
|
||||
if (!existsSync(originalUploadFolder)) {
|
||||
mkdirSync(originalUploadFolder, { recursive: true });
|
||||
@@ -41,8 +38,9 @@ export const assetUploadOption: MulterOptions = {
|
||||
|
||||
filename: (req: Request, file: Express.Multer.File, cb: any) => {
|
||||
const fileNameUUID = randomUUID();
|
||||
const fileName = `${fileNameUUID}${req.body['fileExtension'].toLowerCase()}`;
|
||||
|
||||
cb(null, `${fileNameUUID}${req.body['fileExtension'].toLowerCase()}`);
|
||||
cb(null, sanitize(fileName));
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import { existsSync, mkdirSync } from 'fs';
|
||||
import { diskStorage } from 'multer';
|
||||
import { extname } from 'path';
|
||||
import { Request } from 'express';
|
||||
import sanitize from 'sanitize-filename';
|
||||
|
||||
export const profileImageUploadOption: MulterOptions = {
|
||||
fileFilter: (req: Request, file: any, cb: any) => {
|
||||
@@ -35,8 +36,9 @@ export const profileImageUploadOption: MulterOptions = {
|
||||
return;
|
||||
}
|
||||
const userId = req.user.id;
|
||||
const fileName = `${userId}${extname(file.originalname)}`;
|
||||
|
||||
cb(null, `${userId}${extname(file.originalname)}`);
|
||||
cb(null, sanitize(fileName));
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { APP_UPLOAD_LOCATION } from '@app/common';
|
||||
import { ImmichLogLevel } from '@app/common/constants/log-level.constant';
|
||||
import { AssetEntity, AssetType } from '@app/database/entities/asset.entity';
|
||||
import {
|
||||
@@ -19,9 +20,11 @@ import { Job, Queue } from 'bull';
|
||||
import ffmpeg from 'fluent-ffmpeg';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { existsSync, mkdirSync } from 'node:fs';
|
||||
import sanitize from 'sanitize-filename';
|
||||
import sharp from 'sharp';
|
||||
import { Repository } from 'typeorm/repository/Repository';
|
||||
import { CommunicationGateway } from '../../../immich/src/api-v1/communication/communication.gateway';
|
||||
import { join } from 'path';
|
||||
import { CommunicationGateway } from 'apps/immich/src/api-v1/communication/communication.gateway';
|
||||
|
||||
@Processor(thumbnailGeneratorQueueName)
|
||||
export class ThumbnailGeneratorProcessor {
|
||||
@@ -46,9 +49,12 @@ export class ThumbnailGeneratorProcessor {
|
||||
|
||||
@Process({ name: generateJPEGThumbnailProcessorName, concurrency: 3 })
|
||||
async generateJPEGThumbnail(job: Job<JpegGeneratorProcessor>) {
|
||||
const { asset } = job.data;
|
||||
const basePath = APP_UPLOAD_LOCATION;
|
||||
|
||||
const resizePath = `upload/${asset.userId}/thumb/${asset.deviceId}/`;
|
||||
const { asset } = job.data;
|
||||
const sanitizedDeviceId = sanitize(asset.deviceId);
|
||||
|
||||
const resizePath = join(basePath, asset.userId, 'thumb', sanitizedDeviceId);
|
||||
|
||||
if (!existsSync(resizePath)) {
|
||||
mkdirSync(resizePath, { recursive: true });
|
||||
|
||||
Reference in New Issue
Block a user