{"version":3,"file":"mime-validation.mjs","sources":["../../../server/src/utils/mime-validation.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport { lookup } from 'mime-types';\nimport type { Core } from '@strapi/types';\nimport { errors } from '@strapi/utils';\n\nexport type SecurityConfig = {\n  allowedTypes?: string[];\n  deniedTypes?: string[];\n};\ntype UploadValidationError = {\n  code: 'MIME_TYPE_NOT_ALLOWED' | 'VALIDATION_ERROR' | 'UNKNOWN_ERROR';\n  message: string;\n  details: Record<string, any>;\n};\n\ntype ValidationResult = {\n  isValid: boolean;\n  error?: UploadValidationError;\n  detectedMime?: string;\n};\n\ntype ErrorDetail = {\n  file: any;\n  originalIndex: number;\n  error: UploadValidationError;\n};\n\nasync function readFileChunk(filePath: string, chunkSize: number = 4100): Promise<Buffer> {\n  const buffer = await readFile(filePath);\n  return buffer.length > chunkSize ? buffer.subarray(0, chunkSize) : buffer;\n}\n\nexport async function detectMimeType(file: any): Promise<string | undefined> {\n  let buffer: Buffer;\n\n  // Support multiple property names used by different multipart parsers (formidable uses filepath)\n  const filePath = file.filepath ?? file.path ?? file.tempFilePath ?? file.filePath;\n\n  if (filePath) {\n    try {\n      buffer = await readFileChunk(filePath, 4100);\n    } catch (error) {\n      throw new Error(\n        `Failed to read file: ${error instanceof Error ? error.message : String(error)}`\n      );\n    }\n  } else if (file.buffer) {\n    buffer = file.buffer.length > 4100 ? file.buffer.subarray(0, 4100) : file.buffer;\n  } else {\n    // No file path or buffer; cannot detect MIME. Validation will use declared/extension or reject.\n    return undefined;\n  }\n\n  try {\n    /**\n     * Use dynamic import to support file-type which is ESM-only\n     * Static imports fail during CommonJS build since bundler can't transform ESM-only packages\n     * @see https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n     */\n    const { fileTypeFromBuffer } = await import('file-type');\n\n    const result = await fileTypeFromBuffer(new Uint8Array(buffer));\n    return result?.mime;\n  } catch (error) {\n    throw new Error(\n      `Failed to detect MIME type: ${error instanceof Error ? error.message : String(error)}`\n    );\n  }\n}\n\nfunction matchesMimePattern(mimeType: string, patterns: string[]): boolean {\n  if (!patterns?.length) return false;\n\n  return patterns.some((pattern) => {\n    const normalizedPattern = pattern.toLowerCase();\n    const normalizedMimeType = mimeType.toLowerCase();\n\n    if (normalizedPattern.includes('*')) {\n      const regexPattern = normalizedPattern.replace(/\\*/g, '.*');\n\n      const regex = new RegExp(`^${regexPattern}$`);\n      const matches = regex.test(normalizedMimeType);\n      return matches;\n    }\n\n    const exactMatch = normalizedPattern === normalizedMimeType;\n    return exactMatch;\n  });\n}\n\nexport function isMimeTypeAllowed(mimeType: string, config: SecurityConfig): boolean {\n  const { allowedTypes, deniedTypes } = config;\n\n  if (!mimeType) return false;\n\n  if (deniedTypes?.length && matchesMimePattern(mimeType, deniedTypes)) {\n    return false;\n  }\n\n  if (Array.isArray(allowedTypes)) {\n    return allowedTypes.length > 0 && matchesMimePattern(mimeType, allowedTypes);\n  }\n\n  return true;\n}\n\n/**\n * Single gate for allow/deny. Returns ValidationResult.\n * Doc: docs/docs/01-core/upload/01-backend/01-mime-validation.md\n */\nfunction validateAllowBanLists(\n  mimetype: string,\n  fileName: string,\n  declaredType: string,\n  detectedType: string | undefined,\n  config: SecurityConfig\n): ValidationResult {\n  if (!mimetype) {\n    return {\n      isValid: false,\n      error: {\n        code: 'MIME_TYPE_NOT_ALLOWED',\n        message: 'MIME type is not allowed',\n        details: {\n          fileName,\n          reason: 'No MIME type to validate',\n          declaredType,\n          detectedType,\n          allowedTypes: config.allowedTypes,\n          deniedTypes: config.deniedTypes,\n        },\n      },\n    };\n  }\n  if (config.deniedTypes?.length && matchesMimePattern(mimetype, config.deniedTypes)) {\n    return buildNotAllowedError(fileName, declaredType, detectedType, mimetype, config);\n  }\n  if (!Array.isArray(config.allowedTypes)) {\n    return { isValid: true, detectedMime: mimetype };\n  }\n  if (config.allowedTypes.length === 0) {\n    return {\n      isValid: false,\n      error: {\n        code: 'MIME_TYPE_NOT_ALLOWED',\n        message: 'MIME type is not allowed',\n        details: {\n          fileName,\n          reason: 'Allow list is empty',\n          declaredType,\n          detectedType,\n          allowedTypes: config.allowedTypes,\n          deniedTypes: config.deniedTypes,\n        },\n      },\n    };\n  }\n  if (matchesMimePattern(mimetype, config.allowedTypes)) {\n    return { isValid: true, detectedMime: mimetype };\n  }\n  return {\n    isValid: false,\n    error: {\n      code: 'MIME_TYPE_NOT_ALLOWED',\n      message: `File type '${mimetype}' is not allowed`,\n      details: {\n        fileName,\n        declaredType,\n        detectedType,\n        finalType: mimetype,\n        allowedTypes: config.allowedTypes,\n        deniedTypes: config.deniedTypes,\n      },\n    },\n  };\n}\n\nfunction isDeclaredGeneric(declaredMimeType: string): boolean {\n  return !declaredMimeType || declaredMimeType === 'application/octet-stream';\n}\n\nexport function extractFileInfo(file: any) {\n  const fileName =\n    file.originalFilename ||\n    file.name ||\n    file.filename ||\n    file.newFilename ||\n    file.originalname ||\n    'unknown';\n  const declaredMimeType = file.mimetype || file.type || file.mimeType || file.mime || '';\n\n  return { fileName, declaredMimeType };\n}\n\nexport async function validateFile(\n  file: any,\n  config: SecurityConfig,\n  strapi: Core.Strapi\n): Promise<ValidationResult> {\n  const { allowedTypes, deniedTypes } = config;\n\n  const { fileName, declaredMimeType } = extractFileInfo(file);\n\n  const fileExt = extname(fileName).toLowerCase();\n  const expectedMimeFromExt = fileExt ? lookup(fileExt) || null : null;\n\n  // Reject if declared type is denied.\n  if (\n    !isDeclaredGeneric(declaredMimeType) &&\n    deniedTypes?.length &&\n    matchesMimePattern(declaredMimeType, deniedTypes)\n  ) {\n    return buildNotAllowedError(fileName, declaredMimeType, undefined, declaredMimeType, config);\n  }\n\n  // Reject if extension's type is denied.\n  if (\n    expectedMimeFromExt &&\n    deniedTypes?.length &&\n    matchesMimePattern(expectedMimeFromExt, deniedTypes)\n  ) {\n    return buildNotAllowedError(fileName, declaredMimeType, undefined, expectedMimeFromExt, config);\n  }\n\n  // Run content detection.\n  let detectedMime: string | undefined;\n  try {\n    detectedMime = await detectMimeType(file);\n  } catch (error) {\n    const errMsg = error instanceof Error ? error.message : String(error);\n    strapi.log.warn(`Failed to detect MIME type from file: ${errMsg}`, {\n      fileName,\n      error: errMsg,\n    });\n  }\n\n  const declaredMatchesExtension =\n    !isDeclaredGeneric(declaredMimeType) &&\n    expectedMimeFromExt !== null &&\n    expectedMimeFromExt !== undefined &&\n    (matchesMimePattern(declaredMimeType, [expectedMimeFromExt]) ||\n      matchesMimePattern(expectedMimeFromExt, [declaredMimeType]));\n  const detectedMatchesDeclared =\n    detectedMime && declaredMimeType && matchesMimePattern(detectedMime, [declaredMimeType]);\n\n  // Trusted declaration: declared matches extension and detection confirms.\n  if (declaredMatchesExtension && detectedMatchesDeclared) {\n    return validateAllowBanLists(\n      declaredMimeType,\n      fileName,\n      declaredMimeType,\n      detectedMime,\n      config\n    );\n  }\n\n  // Reject if detected type is denied.\n  if (detectedMime && deniedTypes?.length && matchesMimePattern(detectedMime, deniedTypes)) {\n    return buildNotAllowedError(fileName, declaredMimeType, detectedMime, detectedMime, config);\n  }\n\n  // Reject if detected is not in allow list (extension/declared cannot override).\n  // Exception: file-type often returns application/zip for Office formats (docx, xlsx); skip so the next block can allow via extension type.\n  const isZipWithAllowedExt =\n    detectedMime === 'application/zip' &&\n    expectedMimeFromExt &&\n    expectedMimeFromExt !== 'application/zip' &&\n    Array.isArray(allowedTypes) &&\n    allowedTypes.length > 0 &&\n    matchesMimePattern(expectedMimeFromExt, allowedTypes);\n  if (\n    detectedMime &&\n    Array.isArray(allowedTypes) &&\n    allowedTypes.length > 0 &&\n    !matchesMimePattern(detectedMime, allowedTypes) &&\n    !isZipWithAllowedExt\n  ) {\n    return {\n      isValid: false,\n      error: {\n        code: 'MIME_TYPE_NOT_ALLOWED',\n        message: 'MIME type is not allowed',\n        details: {\n          fileName,\n          reason:\n            'File content was detected as a type not in the allow list; extension or declared type cannot override',\n          declaredType: declaredMimeType,\n          detectedType: detectedMime,\n          expectedMimeFromExtension: expectedMimeFromExt,\n          allowedTypes,\n          deniedTypes,\n        },\n      },\n    };\n  }\n\n  // Use detected type when defined and (no extension, or detected matches extension, or declared is generic).\n  const detectedMatchesExtension =\n    detectedMime &&\n    expectedMimeFromExt !== null &&\n    expectedMimeFromExt !== undefined &&\n    matchesMimePattern(detectedMime, [expectedMimeFromExt]);\n  if (\n    detectedMime &&\n    (!expectedMimeFromExt || detectedMatchesExtension || isDeclaredGeneric(declaredMimeType))\n  ) {\n    // Office/zip exception: use extension type when detection returned application/zip and extension is in allow list.\n    if (\n      detectedMime === 'application/zip' &&\n      expectedMimeFromExt &&\n      expectedMimeFromExt !== 'application/zip'\n    ) {\n      const extResult = validateAllowBanLists(\n        expectedMimeFromExt,\n        fileName,\n        declaredMimeType,\n        detectedMime,\n        config\n      );\n      if (extResult.isValid) {\n        strapi.log.warn(\n          'MIME type detection returned application/zip; trusting extension for allow list',\n          { fileName, fileExtension: fileExt, expectedMimeFromExtension: expectedMimeFromExt }\n        );\n        return extResult;\n      }\n    }\n    return validateAllowBanLists(detectedMime, fileName, declaredMimeType, detectedMime, config);\n  }\n\n  // Use extension's type when present.\n  if (expectedMimeFromExt) {\n    return validateAllowBanLists(\n      expectedMimeFromExt,\n      fileName,\n      declaredMimeType,\n      detectedMime,\n      config\n    );\n  }\n\n  // Use declared type as last resort.\n  if (declaredMimeType) {\n    return validateAllowBanLists(\n      declaredMimeType,\n      fileName,\n      declaredMimeType,\n      detectedMime,\n      config\n    );\n  }\n\n  // Reject when no type can be chosen.\n  return {\n    isValid: false,\n    error: {\n      code: 'MIME_TYPE_NOT_ALLOWED',\n      message: 'Cannot verify file type for security reasons',\n      details: {\n        fileName,\n        reason: 'No MIME type to validate (no declared type, no extension, no detection)',\n        declaredType: declaredMimeType,\n        detectedType: detectedMime,\n        allowedTypes,\n        deniedTypes,\n      },\n    },\n  };\n}\n\nfunction buildNotAllowedError(\n  fileName: string,\n  declaredType: string,\n  detectedType: string | undefined,\n  rejectedType: string,\n  config: SecurityConfig\n): ValidationResult {\n  return {\n    isValid: false,\n    error: {\n      code: 'MIME_TYPE_NOT_ALLOWED',\n      message: `File type '${rejectedType}' is not allowed`,\n      details: {\n        fileName,\n        declaredType,\n        detectedType,\n        finalType: rejectedType,\n        allowedTypes: config.allowedTypes,\n        deniedTypes: config.deniedTypes,\n        reason: 'MIME type is in the denied list',\n      },\n    },\n  };\n}\n\nexport async function validateFiles(files: any, strapi: Core.Strapi): Promise<ValidationResult[]> {\n  const filesArray = Array.isArray(files) ? files : [files];\n\n  if (!filesArray.length) {\n    return [];\n  }\n\n  // Use array path so 'plugin::upload' is a single key (lodash string path splits on '.')\n  let config: SecurityConfig = strapi.config.get(\n    ['plugin::upload', 'security'],\n    {}\n  ) as SecurityConfig;\n  if (!config || typeof config !== 'object') {\n    config = {};\n  }\n  if (\n    config.allowedTypes &&\n    (!Array.isArray(config.allowedTypes) ||\n      !config.allowedTypes.every((item) => typeof item === 'string'))\n  ) {\n    throw new errors.ApplicationError(\n      'Invalid configuration: allowedTypes must be an array of strings.'\n    );\n  }\n\n  if (\n    config.deniedTypes &&\n    (!Array.isArray(config.deniedTypes) ||\n      !config.deniedTypes.every((item) => typeof item === 'string'))\n  ) {\n    throw new errors.ApplicationError(\n      'Invalid configuration: deniedTypes must be an array of strings.'\n    );\n  }\n\n  if (!config.allowedTypes && !config.deniedTypes) {\n    strapi.log.warn(\n      'No upload security configuration found. Consider configuring plugin.upload.security for enhanced file validation.'\n    );\n    // Do not return; we still run validation so MIME detection runs and stored file gets detected type when possible\n  }\n\n  const validationPromises = filesArray.map(async (file, index) => {\n    try {\n      return await validateFile(file, config, strapi);\n    } catch (error) {\n      strapi.log.error('Unexpected error during file validation', {\n        fileIndex: index,\n        fileName: file?.name || file?.originalname,\n        error: error instanceof Error ? error.message : String(error),\n      });\n\n      return {\n        isValid: false,\n        error: {\n          code: 'VALIDATION_ERROR' as const,\n          message: `Validation failed for file at index ${index}`,\n          details: {\n            index,\n            fileName: file?.name || file?.originalname,\n            originalError: error instanceof Error ? error.message : String(error),\n          },\n        },\n      };\n    }\n  });\n\n  return Promise.all(validationPromises);\n}\n\nexport async function enforceUploadSecurity(\n  files: any,\n  strapi: Core.Strapi\n): Promise<{\n  validFiles: any[];\n  validFileNames: string[];\n  errors: Array<ErrorDetail>;\n}> {\n  const validationResults = await validateFiles(files, strapi);\n  const filesArray = Array.isArray(files) ? files : [files];\n\n  const validFiles: any[] = [];\n  const validFileNames: string[] = [];\n  const errors: Array<ErrorDetail> = [];\n\n  for (const [index, result] of validationResults.entries()) {\n    if (result.isValid) {\n      const file = filesArray[index];\n      // Enrich file with detected MIME type for use in storage\n      if (result.detectedMime) {\n        file.detectedMimeType = result.detectedMime;\n      }\n      validFiles.push(file);\n      validFileNames.push(file.originalFilename || file.name);\n    } else if (result.error) {\n      errors.push({\n        file: filesArray[index],\n        originalIndex: index,\n        error: result.error,\n      });\n    } else {\n      // Handle case where validation failed but no error details are provided\n      errors.push({\n        file: filesArray[index],\n        originalIndex: index,\n        error: {\n          code: 'UNKNOWN_ERROR' as const,\n          message: 'File validation failed for unknown reason',\n          details: {\n            index,\n            fileName: filesArray[index]?.name || filesArray[index]?.originalname,\n          },\n        },\n      });\n    }\n  }\n\n  return { validFiles, validFileNames, errors };\n}\n\nexport type FileUploadError = {\n  name: string;\n  message: string;\n};\n\nexport type PrepareUploadResult = {\n  validFiles: any[];\n  filteredBody: any;\n  errors: FileUploadError[];\n};\n\n/**\n * Prepare files and body for upload by enforcing security and parsing fileInfo\n */\nexport async function prepareUploadRequest(\n  filesInput: any,\n  body: any,\n  strapi: Core.Strapi\n): Promise<PrepareUploadResult> {\n  const securityResults = await enforceUploadSecurity(filesInput, strapi);\n\n  let filteredBody = body;\n  if (body?.fileInfo) {\n    // Parse JSON strings in fileInfo\n    let parsedFileInfo = body.fileInfo;\n    if (Array.isArray(body.fileInfo)) {\n      parsedFileInfo = body.fileInfo.map((fi: any) =>\n        typeof fi === 'string' ? JSON.parse(fi) : fi\n      );\n    } else if (typeof body.fileInfo === 'string') {\n      parsedFileInfo = JSON.parse(body.fileInfo);\n    }\n\n    // Filter fileInfo by index - only keep entries for files that passed validation\n    if (Array.isArray(parsedFileInfo)) {\n      const invalidIndices = new Set(securityResults.errors.map((e) => e.originalIndex));\n      const filteredFileInfo = parsedFileInfo.filter(\n        (_: any, index: number) => !invalidIndices.has(index)\n      );\n\n      if (filteredFileInfo.length === 1) {\n        filteredBody = {\n          ...body,\n          fileInfo: filteredFileInfo[0],\n        };\n      } else {\n        filteredBody = {\n          ...body,\n          fileInfo: filteredFileInfo,\n        };\n      }\n    } else {\n      filteredBody = {\n        ...body,\n        fileInfo: parsedFileInfo,\n      };\n    }\n  }\n\n  // Map errors to simplified format\n  const uploadErrors: FileUploadError[] = securityResults.errors.map((e) => ({\n    name: e.file?.originalFilename || e.file?.name || 'unknown',\n    message: e.error.message,\n  }));\n\n  return {\n    validFiles: securityResults.validFiles,\n    filteredBody,\n    errors: uploadErrors,\n  };\n}\n"],"names":["readFileChunk","filePath","chunkSize","buffer","readFile","length","subarray","detectMimeType","file","filepath","path","tempFilePath","error","Error","message","String","undefined","fileTypeFromBuffer","result","Uint8Array","mime","matchesMimePattern","mimeType","patterns","some","pattern","normalizedPattern","toLowerCase","normalizedMimeType","includes","regexPattern","replace","regex","RegExp","matches","test","exactMatch","validateAllowBanLists","mimetype","fileName","declaredType","detectedType","config","isValid","code","details","reason","allowedTypes","deniedTypes","buildNotAllowedError","Array","isArray","detectedMime","finalType","isDeclaredGeneric","declaredMimeType","extractFileInfo","originalFilename","name","filename","newFilename","originalname","type","validateFile","strapi","fileExt","extname","expectedMimeFromExt","lookup","errMsg","log","warn","declaredMatchesExtension","detectedMatchesDeclared","isZipWithAllowedExt","expectedMimeFromExtension","detectedMatchesExtension","extResult","fileExtension","rejectedType","validateFiles","files","filesArray","get","every","item","errors","ApplicationError","validationPromises","map","index","fileIndex","originalError","Promise","all","enforceUploadSecurity","validationResults","validFiles","validFileNames","entries","detectedMimeType","push","originalIndex","prepareUploadRequest","filesInput","body","securityResults","filteredBody","fileInfo","parsedFileInfo","fi","JSON","parse","invalidIndices","Set","e","filteredFileInfo","filter","_","has","uploadErrors"],"mappings":"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"}