Scanning File Uploads in Umbraco Forms (Azure Blob...
# help-with-umbraco
p
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!
t
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.
d
Hi @Piotr Król We achieved this using Microsoft Defender for Storage: https://learn.microsoft.com/en-us/azure/defender-for-cloud/on-upload-malware-scanning We have Microsoft Defender for Storage scan the upload and delete it if it detects anything suspicious almost instantly.
j
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?
Copy code
csharp
```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;
        }
    }
j
I came here to suggest a custom upload too, great minds eh
p
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 😀
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
j
If ValidateField returns errors, then none of the files uploaded for this field will be persisted.
p
Ok great, thank you!
37 Views