Limit upload to PDFs only

For uploading PDFs, I have to select “file” in upload settings of a collection. that means the user can upload anything using the API directly.

This is a security issue for us. imagine someone uploading a virus using our Strapi public API (which is used for contact us) and share the upload url with one of our users. They might open it up and get hacked. same can be done with HTML and phishing on mass scale.

I think this is a huge issue in general. I should be able to limit filetype when creating a collection to lets say PDF only. This is both useful and safer

Until this feature is developed (if ever), how can I do this myself?

You may be able to check the file info and add customizations using our extensions system here: strapi/upload.js at master · strapi/strapi · GitHub

We don’t currently have sample code to do a POC but we do understand limiting the file types is a nice feature to have.

1 Like

I’d appreciate it if you give me a little more details on how to do this?

I’ve honestly never attempted it, I can try and take a look during the week but I’ll be in the same boat as you :wink:

I do my best to point users in the right direction but try to avoid a copy/paste type answer.

1 Like

I’d appreciate it. I won’t copy paste it, promise. I did manage to write a plugin for adding pictures into editor using same level of help here in this forum.

thanks

Hi!, You can use this article :

But you have to replace formatFileInfo with enhanceAndValidateFile method and add some logic to check file extention like below.

src/extensions/upload/overrides.ts

const os = require('os');
const path = require('path');
const crypto = require('crypto');
const fs = require('fs');
const fse = require('fs-extra');
const _ = require('lodash');
const { extension } = require('mime-types');
const {
  sanitize,
  nameToSlug,
  contentTypes: contentTypesUtils,
  webhook: webhookUtils,
} = require('@strapi/utils');
const { NotFoundError } = require('@strapi/utils').errors;

const { MEDIA_UPDATE, MEDIA_CREATE, MEDIA_DELETE } = webhookUtils.webhookEvents;

const { ApplicationError } = require('@strapi/utils/lib/errors');


const isFileExtensionAllowed = async (fileExtension) => {
    const allowedExtensions = ['.jpg', '.jpeg', '.png', '.mp4', '.mp3', '.wav', '.txt', '.doc', '.docx'];
    return allowedExtensions.includes(fileExtension);
  }

/**
 * Overriding enhanceAndValidateFile function for upload plugin to
 * validate original file type. node_modules/@strapi/plugin-upload/server/services/upload.js
 */
export async function enhanceAndValidateFile(file, fileInfo = {}, metas = {}) {
    const currentFile = await this.formatFileInfo(
        {
          filename: file.name,
          type: file.type,
          size: file.size,
        },
        fileInfo,
        {
          ...metas,
          tmpWorkingDirectory: file.tmpWorkingDirectory,
        }
      );

      if (! await isFileExtensionAllowed(currentFile?.ext)) {
        throw new ApplicationError('File type is not a valid.');
      }

      currentFile.getStream = () => fs.createReadStream(file.path);
  
      const { optimize, isImage, isFaultyImage, isOptimizableImage } = strapi
        .plugin('upload')
        .service('image-manipulation');
  
      if (await isImage(currentFile)) {
        if (await isFaultyImage(currentFile)) {
          throw new ApplicationError('File is not a valid image');
        }
        if (await isOptimizableImage(currentFile)) {
          return optimize(currentFile);
        }
      }
      return currentFile;
}