diff --git a/src/services/uploads/src/clamav.ts b/src/services/uploads/src/clamav.ts index 4a9476582d..8eb821d25d 100644 --- a/src/services/uploads/src/clamav.ts +++ b/src/services/uploads/src/clamav.ts @@ -11,7 +11,7 @@ import fs from "fs"; import asyncfs from "fs/promises"; import * as constants from "./constants"; import * as utils from "./utils"; -import {FileExtension, MimeType, fileTypeFromFile} from 'file-type'; +import { FileExtension, MimeType, fileTypeFromFile } from "file-type"; const s3Client: S3Client = new S3Client(); @@ -207,33 +207,31 @@ export const uploadAVDefinitions = async (): Promise => { * * @param pathToFile Path in the filesystem where the file is stored. */ -export const scanLocalFile = async (pathToFile: string, contentType: string | undefined): Promise => { +export const scanLocalFile = async ( + pathToFile: string, + contentType: string | undefined +): Promise => { try { - if(!contentType){ + if (!contentType) { utils.generateSystemMessage("FAILURE - EXTENSION UNKNOWN"); return constants.STATUS_UNKNOWN_EXTENSION; } let detectedContentType = await getFileTypeFromContents(pathToFile); - if(detectedContentType){ - console.log(`File declared extension: ${contentType}`); - console.log(`File detected extension: ${detectedContentType}`) - let same = areMimeTypesEquivalent(contentType, detectedContentType) - if(!same){ - utils.generateSystemMessage(`FAILURE - FILE EXTENSION DOES NOT MATCH FILE CONTENTS`); - return constants.STATUS_EXTENSION_MISMATCH_FILE + if (detectedContentType) { + console.log(`File declared extension: ${contentType}`); + console.log(`File detected extension: ${detectedContentType}`); + let same = areMimeTypesEquivalent(contentType, detectedContentType); + if (!same) { + utils.generateSystemMessage( + `FAILURE - FILE EXTENSION DOES NOT MATCH FILE CONTENTS` + ); + return constants.STATUS_EXTENSION_MISMATCH_FILE; } } const avResult: SpawnSyncReturns = spawnSync( constants.PATH_TO_CLAMAV, - [ - "--stdout", - "-v", - "-a", - "-d", - constants.FRESHCLAM_WORK_DIR, - pathToFile, - ] + ["--stdout", "-v", "-a", "-d", constants.FRESHCLAM_WORK_DIR, pathToFile] ); // status 1 means that the file is infected. @@ -259,42 +257,47 @@ export const scanLocalFile = async (pathToFile: string, contentType: string | un } }; -async function getFileTypeFromContents(filePath: string): Promise { +async function getFileTypeFromContents( + filePath: string +): Promise { try { - const fileBuffer = await fs.promises.readFile(filePath); + const fileBuffer = await fs.promises.readFile(filePath); - // Get the file type from its contents - const type = await fileTypeFromFile(filePath); + // Get the file type from its contents + const type = await fileTypeFromFile(filePath); - if (!type) { - console.log('Could not determine file type.'); - return null; - } - console.log(`File type is ${type.mime} with extension ${type.ext}`); - return type.mime + if (!type) { + console.log("Could not determine file type."); + return null; + } + console.log(`File type is ${type.mime} with extension ${type.ext}`); + return type.mime; } catch (error) { - console.error('Error reading file:', error); - return null + console.error("Error reading file:", error); + return null; } } function areMimeTypesEquivalent(mime1: string, mime2: string): boolean { const equivalentTypes: { [key: string]: Set } = { - 'application/rtf': new Set(['text/rtf']), - 'application/vnd.ms-excel': new Set(['application/x-cfb']), - 'application/vnd.ms-powerpoint': new Set(['application/x-cfb']), - 'application/msword': new Set(['application/x-cfb']) + "application/rtf": new Set(["text/rtf"]), + "application/vnd.ms-excel": new Set(["application/x-cfb"]), + "application/vnd.ms-powerpoint": new Set(["application/x-cfb"]), + "application/msword": new Set(["application/x-cfb", "application/rtf"]), }; mime1 = mime1.toLowerCase(); mime2 = mime2.toLowerCase(); if (mime1 === mime2) { - return true; + return true; } for (const baseType in equivalentTypes) { - const equivalents = equivalentTypes[baseType]; - if ((mime1 === baseType && equivalents.has(mime2)) || (mime2 === baseType && equivalents.has(mime1))) { - return true; - } + const equivalents = equivalentTypes[baseType]; + if ( + (mime1 === baseType && equivalents.has(mime2)) || + (mime2 === baseType && equivalents.has(mime1)) + ) { + return true; + } } return false; -} \ No newline at end of file +}