How to check uploaded file format?

Hello!

I have the standard user model with an avatar field (single media field). In admin panel I set images allowed types of media. Now, I want to allow users to upload their avatars by a special API endpoint. To implement this endpoint, I use the following code:

const attachment = await strapi.plugins.upload.services.upload.upload({
        data: {
             refId: user.id,
             ref: 'plugin::users-permissions.user',
             field: 'avatar',
        },
        files: avatar,
});

But this function doesn’t check the format of uploaded file. How to check the file format that the user uploads correctly? So that this check coincides with the format restrictions set in the admin panel.

Hi…
i have this in config/myFunctions/utils.js

module.exports = {
  CheckImages(files) {
    var claves = Object.keys(files);
    const validTypes = ["image/jpeg", "image/jpg", "image/bmp", "image/png"]

    for (let i = 0; i < claves.length; i++) {
      const clave = claves[i];
      const valor = files[clave];
      if (!validTypes.includes(valor.type)) {
        return false;
      }
    }
    return true;
  },
}

and in the endpoint

const { CheckImages } = require("../../../../config/myFunctions/utils");
const files = ctx.request.files;
    if (files) {
      if (!CheckImages(files))
        return ctx.badRequest('Formato de imagen no válido');
    }

You can use middlewares at api level to throw an error on restricted file types.

I implemented this in my global middleware, you can implement it at route level as well.- Middlewares | Strapi Documentation

I have this in my api/middlewares/fileCheck.js

module.exports = (config, { strapi }) => {
  // Add your own logic here.

  return async (ctx, next) => {
    strapi.log.info("In file-check middleware.");
    
    const reqBody = ctx.request.body.fileInfo;
    const fileInfo1 = reqBody;

    if (ctx.request.url === "/upload") {
      console.log(ctx.request.body, "upload");
      const parsedFileInfo = ctx.request.body.fileInfo;
      const file = JSON.parse(parsedFileInfo);
      const restrictedExtensions = [
        ".exe",
        ".bat",
        ".msi",
        ".com",
        ".cmd",
        ".vbs",
        ".scr",
        ".js",
        ".ps1",
        ".php",
        ".py",
        ".pl",
        ".rb",
        ".sh",
        ".jsp",
        ".zip",
        ".rar",
        ".tar",
        ".gz",
        ".7z",
        ".bz2",
        ".xz",
        ".ini",
        ".config",
        ".xml",
        ".yml",
        ".json",
        ".sql",
        ".db",
        ".mdb",
        ".accdb",
        ".msh",
        ".app",
        ".elf",
        ".html",
        ".htm",
        ".css",
        ".js",
        ".php",
        ".docm",
        ".xlsm",
        ".pptm",
        ".dotm",
        ".potm",
        ".xltm",
        ".xltx",
        ".xlam",
        ".key",
        ".pem",
        ".pfx",
        ".asc",
        ".locky",
        ".zepto",
        ".cerber",
        ".astra",
        ".kraken",
        ".diablo",
      ];
      // const doubleExtensionRegex = /(\.\w+){2,}$/;
      const fileName = `.${file.name.split(".").pop()}`;
      if (restrictedExtensions.includes(fileName)) {
        throw new Error("Invalid file type");
      }
      // Check for double extensions

      const fileParts = file.name.split('.');


        for (let i = 1; i < fileParts.length - 1; i++) {
          if (
            !restrictedExtensions.some((restrictedExt) =>
              fileParts[i].endsWith(restrictedExt)
            )
          ) {
            throw new Error(
              "Invalid file format. Files with restricted extensions are not allowed."
            );
          }
        }

    }

    await next();
  };
};

1 Like