0

I'm calling an API that accepts a maximum of six files, combined total size cannot be over 15Mb and allowed file types are: pdf, doc, docx, xls, xlsx, jpeg, jpg, gif, png, txt.

I have a method called TryAddAttachment that can be used to check if requirements are met. However there is nothing stopping a programmer calling the code like below instead and then bypassing the checks. What is the best way to prevent this or is there a better solution to the problem described above?

var contactForm = new ContactForm();

var file = new FileAttachment();
file.FileName = "Test.txt";
file.Content = Encoding.ASCII.GetBytes("Test text");

contactForm.Attachments.Add(file);

Current code:

public class ContactForm
{
    private readonly List<FileAttachment> _attachments;

    private readonly string[] _validExtensions = { ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".jpeg", ".jpg", ".gif", ".png", ".txt" };

    public ContactForm()
    {
        _attachments = new List<FileAttachment>();
    }

    public string Name { get; set; }

    public string Email { get; set; }

    public string Phone { get; set; }

    public string SocialSecurityNumber { get; set; }

    public string Message { get; set; }

    public List<FileAttachment> Attachments
    {
        get { return _attachments; }
    }

    public bool TryAddAttachment(FileAttachment attachment)
    {
        if (_attachments.Count + 1 > 6)
        {
            return false;
        }

        var extension = Path.GetExtension(attachment.FileName);

        if (!IsValidExtension(extension))
        {
            return false;
        }

        long totalSize = 0;

        foreach (var fileAttachment in _attachments)
        {
            totalSize += fileAttachment.Content.Length;
        }

        if (totalSize + attachment.Content.Length > 15000000)
        {
            return false;
        }

        _attachments.Add(attachment);
        return true;
    }

    private bool IsValidExtension(string ext)
    {
        return _validExtensions.Contains(ext);
    }

}

public class FileAttachment
{
    public string FileName { get; set; }

    public string ContentType
    {
        get
        {
            if (!string.IsNullOrWhiteSpace(FileName))
            {
                return MimeMapping.GetMimeMapping(FileName);
            }
            return null;
        }
    }

    public byte[] Content { get; set; }
}

Updated code:

public class ContactForm
{
    private readonly List<FileAttachment> _attachments;

    private readonly string[] _validExtensions = { ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".jpeg", ".jpg", ".gif", ".png", ".txt" };

    public ContactForm()
    {
        _attachments = new List<FileAttachment>();
    }

    public string Name { get; set; }

    public string Email { get; set; }

    public string Phone { get; set; }

    public string SocialSecurityNumber { get; set; }

    public string Message { get; set; }

    /// <summary>
    /// Use AddAttachment to add files
    /// </summary>
    public ReadOnlyCollection<FileAttachment> Attachments
    {
        get { return _attachments.AsReadOnly(); }
    }

    public void AddAttachment(FileAttachment attachment)
    {
        var maximumAttachments = 6;
        if (_attachments.Count + 1 > maximumAttachments)
        {
            throw new Exception($"Maximum attachments is {maximumAttachments}");
        }

        var extension = Path.GetExtension(attachment.FileName);

        if (!IsValidExtension(extension))
        {
            var allowedExtensionsString = string.Join(",", _validExtensions);
            throw new Exception($"Invalid file extension {extension}. Allowed are: {allowedExtensionsString}");
        }

        long totalSize = 0;

        foreach (var fileAttachment in _attachments)
        {
            totalSize += fileAttachment.Content.Length;
        }

        totalSize += attachment.Content.Length;
        var maximumSize = 15000000;

        if (totalSize > maximumSize)
        {
            throw new Exception($"Total size of attachments is to big {totalSize}, maximum is {maximumSize}");

        }

        _attachments.Add(attachment);
    }

    private bool IsValidExtension(string ext)
    {
        return _validExtensions.Contains(ext);
    }

}

public class FileAttachment
{
    public string FileName { get; set; }

    public string ContentType
    {
        get
        {
            if (!string.IsNullOrWhiteSpace(FileName))
            {
                return MimeMapping.GetMimeMapping(FileName);
            }
            return null;
        }
    }

    public byte[] Content { get; set; }
}
Ogglas
  • 62,132
  • 37
  • 328
  • 418

0 Answers0