#Scanning File Uploads in Umbraco Forms (Azure Blob Configuration)

1 messages · Page 1 of 1 (latest)

sturdy linden
#

Hi everyone,

I'm currently working with Umbraco 10.8.6 and Umbraco Forms 10.5.4, with my media stored on Azure Blob Storage. I have a contact form that includes a File Upload field where users can attach a file.

My goal is to scan the file's contents using my existing method, ScanFile()—which takes a Stream representing the file content—before the file is saved in the system to ensure it doesn’t contain any malicious software.

I've tried a few approaches so far:

  1. I attempted to add a custom workflow to validate the file. However, it seems that by the time the workflow runs, the file is already saved in a temporary folder on Azure Blob.

  2. I also tried using the MediaSavingNotification, but it appears that Umbraco Forms bypasses this notification when a file is uploaded via the form.

  3. Additionally, I experimented with something like a FormValidateNotification. In that case, I had access to all the values from the submitted form. However, the file upload field's value appears as a 260-character string that doesn’t contain the file's content; it ends with the attached file's name. I'm not sure what this string represents, and I couldn’t find any documentation about it.

Another idea I had was to add middleware to intercept the HTTP request after the form is submitted. However, that approach feels clunky, and I'm convinced there must be a better way.

Has anyone faced a similar issue or have suggestions on the best approach to scan the file before it is saved? Perhaps there are even better methods that I haven’t considered.

Thanks in advance for your help!

marble cypress
#

I have no good solution for you here, but just as a thought challenge - COULD you do it after the fact?

So new upload is accepted, and afterwards the file is scanned, and if need be take action on something malicious.

arctic knot
nimble abyss
#

If you can upgrade to 13 you will save yourself a bit of work.

13+ has the concept of an IFileStreamSecurityValidator that forms will automatically use to scan files on upload.

Have a look at:

https://docs.umbraco.com/umbraco-forms/13.latest/editor/creating-a-form/fieldtypes/fileupload#server-side-file-validation

And: https://docs.umbraco.com/umbraco-cms/10.latest/reference/security/serverside-file-validation

Otherwise, what I do in v8 (not sure if it works in v10, but worth a try) is to create a custom upload field that replaces the built-in one (create a class that inherits from Umbraco.Forms.Core.Providers.FieldTypes.FileUpload) and then override the ValidateField method (ensuring you call the base method) and then add any additional file checking logic.

#

Maybe something like this?

```csharp
    public class FileCheckingUploadField : Umbraco.Forms.Core.Providers.FieldTypes.FileUpload
    {
        public FileCheckingUploadField(
            IOptions<SecuritySettings> config,
            IHostEnvironment hostEnvironment,
            MediaFileManager mediaFileManager,
            IDataProtectionProvider dataProtectionProvider) : base(config, hostEnvironment, mediaFileManager, dataProtectionProvider)
        {
        }

        public override IEnumerable<string> ValidateField(
            Form form,
            Field field,
            IEnumerable<object> postedValues,
            HttpContext context,
            IPlaceholderParsingService placeholderParsingService,
            IFieldTypeStorage fieldTypeStorage)
        {
            var errors = base.ValidateField(form, field, postedValues, context, placeholderParsingService, fieldTypeStorage).ToList();

            foreach(var file in context.Request.Form.Files)
            {
                // TODO: Make sure you only check the files for this actual field
                // TODO: validate the file
                // I recommend copying the stream to a new memory stream with file.CopyTo() rather than using file.OpenReadStream()
                // TODO: Add an error message to the errors list if the file is invalid
            }

            return errors;
        }
    }
wooden solar
#

I came here to suggest a custom upload too, great minds eh

sturdy linden
#

In my case, Jason's solution of adding a custom FieldType to Umbraco Forms worked best. It was a great idea that solved my problem. After implementing it, I could easily access the file's contents before it was saved in the ValidateField method, and the issue was resolved. Huge thanks to everyone for help 😀

sturdy linden
#

One more question: I want to ensure that if error messages are returned from the ValidateField method, the file won't be saved in any temporary storage

nimble abyss
#

If ValidateField returns errors, then none of the files uploaded for this field will be persisted.