Как обезопасить загрузку файлов через действие контроллера и ajax? - PullRequest
0 голосов
/ 03 февраля 2019

У меня есть приложение, в котором я хочу, чтобы пользователи могли загружать и скачивать свои собственные файлы.Я реализовал загрузку и загрузку, однако меня беспокоит XSS-уязвимость действия загрузки.Я смог реализовать только файл, загружаемый с помощью метода GET, но я хочу защитить его (обычно я использую токен POST + antiforgery).Как я могу это сделать?

Это мое действие контроллера:

        public ActionResult DownloadFile(int clientFileId)
        {
            var clientId = GetClientId(clientFileId);
            var client = _unitOfWork.Clients.GetById(clientId);

            if (client == null)
                return HttpNotFound();

            var file = _unitOfWork.ClientFiles.GetById(clientFileId);

            if (file == null)
                return HttpNotFound();

            var practiceId = _unitOfWork.Users.GetPracticeIdForUser(User.Identity.GetUserId());
            if (!AuthorizationHelper.CheckBelongsToPractice(_unitOfWork.Clients, typeof(Client),
                practiceId, client.Id, nameof(Client.Id), nameof(Client.PracticeId)))            
            {
                return new HttpUnauthorizedResult();
            }

            var fileInfo = new FileInfo(file.FilePath);
            var fileName = fileInfo.Name;

            if (!fileInfo.Exists)
                return HttpNotFound();

            var path = Path.Combine(Server.MapPath("~/ClientFiles/" + clientId + "/"), fileName);
            var contentType = MimeMapping.GetMimeMapping(path);
            try
            {
                var contentDisposition = new System.Net.Mime.ContentDisposition
                {
                    FileName = fileName,
                    Inline = false,                    
                };
                Response.AppendHeader("Content-Disposition", contentDisposition.ToString());
                return File(path, contentType, fileName);
            }
            catch (Exception ex)
            {
                new ExceptionlessLogger(ex).Log();
                return new HttpStatusCodeResult(500);
            }
        }

И мой вызов ajax

       $('#client-files-table').on('click', '.js-download', function () {
        var link = $(this);        
        $.ajax({
            url: '/clients/clientfiles/downloadfile?clientFileId=' + link.attr('data-clientfile-id'),
            method: 'GET',
            //data: {
            //    __RequestVerificationToken: getToken()
            //},
            success: function () {
                window.location = '/clients/clientfiles/downloadfile?clientFileId=' + link.attr('data-clientfile-id'),
                loadPartials();
            },
            error: function () {
                toastr.error('Unable to download.');
            }
        });            
    });

1 Ответ

0 голосов
/ 03 февраля 2019

Я нашел ответ здесь: https://codepen.io/chrisdpratt/pen/RKxJNo

$('#client-files-table').on('click', '.js-download', function () {
        var link = $(this);        
        $.ajax({
            url: '/clients/clientfiles/downloadfile?clientFileId=' + link.attr('data-clientfile-id'),
            method: 'POST',
            data: {
                __RequestVerificationToken: getToken()                
            },            
            xhrFields: {
                responseType: 'blob'
            },
            success: function (data, status, xhr) {
                var a = document.createElement('a');
                var url = window.URL.createObjectURL(data);
                a.href = url;
                var header = xhr.getResponseHeader('Content-Disposition');
                var filename = getFileNameByContentDisposition(header);
                a.download = filename;
                a.click();
                window.URL.revokeObjectURL(url);
                loadPartials();
            },
            error: function () {
                toastr.error('Unable to download.');
            }
        });            
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...