Home » Customization » Restrict Certain Types of Files From Being Uploaded in Sitecore

Restrict Certain Types of Files From Being Uploaded in Sitecore

Sitecore Technology MVP 2016
Sitecore MVP 2015
Sitecore MVP 2014

Enter your email address to follow this blog and receive notifications of new posts by email.

Tweets

Tonight I was struck by a thought while conducting research for a future blog post: should we prevent users from uploading certain types of files in Sitecore for security purposes?

You might thinking “Prevent users from uploading files? Mike, what on Earth are you talking about?”

What I’m suggesting is we might want to consider restricting certain types of files — specifically executables (these have an extension of .exe) and DOS command files (these have an extension of .com) — from being uploaded into Sitecore, especially when files can be easily downloaded from the media library.

Why should we do this?

Doing this will curtail the probability of viruses being spread among our Sitecore users — such could happen if one user uploads an executable that harbors a virus, and other users of our Sitecore system download that tainted executable, and run it on their machines.

As a “proof of concept”, I built the following uiUpload pipeline processor — the uiUpload pipeline lives in /configuration/sitecore/processors/uiUpload in your Sitecore instance’s Web.config — to restrict certain types of files from being uploaded into Sitecore:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;

using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Pipelines.Upload;

namespace Sitecore.Sandbox.Pipelines.Upload
{
    public class CheckForRestrictedFiles : UploadProcessor
    {
        private List<string> _RestrictedExtensions;
        private List<string> RestrictedExtensions
        {
            get
            {
                if (_RestrictedExtensions == null)
                {
                    _RestrictedExtensions = new List<string>();
                }

                return _RestrictedExtensions;
            }
        }

        public void Process(UploadArgs args)
        {
            foreach(string fileKey in args.Files)
            {
                string fileName = GetFileName(args.Files, fileKey);
                string extension = Path.GetExtension(fileName);
                if (IsRestrictedExtension(extension))
                {
                    args.ErrorText = Translate.Text(string.Format("The file \"{0}\" cannot be uploaded. Files with an extension of {1} are not allowed.", fileName, extension));
                    Log.Warn(args.ErrorText, this);
                    args.AbortPipeline();
                }
            }
        }

        private static string GetFileName(HttpFileCollection files, string fileKey)
        {
            Assert.ArgumentNotNull(files, "files");
            Assert.ArgumentNotNullOrEmpty(fileKey, "fileKey");
            return files[fileKey].FileName;
        }

        private bool IsRestrictedExtension(string extension)
        {
            return RestrictedExtensions.Exists(restrictedExtension => string.Equals(restrictedExtension, extension, StringComparison.CurrentCultureIgnoreCase));
        }

        protected virtual void AddRestrictedExtension(XmlNode configNode)
        {
            if (configNode == null || string.IsNullOrWhiteSpace(configNode.InnerText))
            {
                return;
            }

            RestrictedExtensions.Add(configNode.InnerText);
        }
    }
}

The class above ascertains whether each uploaded file has an extension that is restricted — restricted extensions are defined in the configuration file below, and are added to a list of strings via the AddRestrictedExtensions method — and logs an error message when a file possessing a restricted extension is encountered.

I then tied everything together using the following patch configuration file including specifying some file extensions to restrict:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <processors>
      <uiUpload>
        <processor mode="on" type="Sitecore.Sandbox.Pipelines.Upload.CheckForRestrictedFiles, Sitecore.Sandbox" patch:before="processor[@type='Sitecore.Pipelines.Upload.CheckSize, Sitecore.Kernel']">
          <restrictedExtensions hint="raw:AddRestrictedExtension">
            <!-- Be sure to prefix with a dot -->
            <extension>.exe</extension>
            <extension>.com</extension>
          </restrictedExtensions>
        </processor>
      </uiUpload>
    </processors>
  </sitecore>
</configuration>

Let’s try this out.

I went to the media library, and attempted to upload an executable:

upload-exe-dialog_001

After clicking the “Open” button, I was presented with the following:

upload-exe-error

An error in my Sitecore instance’s latest log file conveys why I could not upload the chosen file:

upload-exe-error-log

If you have thoughts on this, or have ideas for other processors that should be added to uiUpload pipeline, please share in a comment.

Advertisements

10 Comments

  1. Paul G. says:

    Mike, I often say, “What on Earth are you thinking about?” but only in the nicest way possible.

  2. Mike, you demonstrated real world practical scenario. Good to learn that.

  3. Amit Celly says:

    Hey Mike,

    I tried your solution, but none of images either .jpg, jpeg, or etc are not getting uploaded in Sitecore instance.

    I may be wrong but I implemented the solution the way you mentioned.

    Regards,
    Amit Celly

  4. Jan Bühler says:

    I’m not satisfied with the “check the log for errors” message as users should be able to get as much feedback as possible. Any clues on how to change the error message?

  5. Jay says:

    Hi Mike, thank you for the reply.
    According to the Doc from Sitecore, they mention

    “The uiUpload pipeline is run not as part of the Sheer event, but as part of the form loading process in response to a post back. This is because the uploaded files are only available during the “real” post back, and not during a Sheer UI event. In this sense, the uiUpload pipeline has not been designed to provide UI. In order to provide feedback to a User, the processor should resort to some trick which emits the JScript code”

    Could I know your idea for detail please??

Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: