Skip to content

Commit

Permalink
validate file upload request. (#3655)
Browse files Browse the repository at this point in the history
* validate file upload request.

Fix #3654.

* including the portal id and user id parameter.
  • Loading branch information
zyhfish committed Apr 1, 2020
1 parent fd590cf commit f6f6ef6
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ public class UploadByUrlDto
public string Filter { get; set; }
public bool IsHostMenu { get; set; }
public int PortalId { get; set; } = -1;
public string ValidationCode { get; set; }
}

[DataContract]
Expand Down Expand Up @@ -389,13 +390,26 @@ private static FileUploadDto UploadFile(
string fileName,
bool overwrite,
bool isHostPortal,
bool extract)
bool extract,
string validationCode)
{
var result = new FileUploadDto();
BinaryReader reader = null;
Stream fileContent = null;
try
{
var extensionList = new List<string>();
if (!string.IsNullOrWhiteSpace(filter))
{
extensionList = filter.Split(',').Select(i => i.Trim()).ToList();
}

var validateParams = new List<object>{ extensionList, portalId, userInfo.UserID};
if (!ValidationUtils.ValidationCodeMatched(validateParams, validationCode))
{
throw new InvalidOperationException("Bad Request");
}

var extension = Path.GetExtension(fileName).ValueOrEmpty().Replace(".", "");
result.FileIconUrl = IconController.GetFileIconUrl(extension);

Expand Down Expand Up @@ -556,6 +570,7 @@ public Task<HttpResponseMessage> UploadFromLocal(int portalId)
var folder = string.Empty;
var filter = string.Empty;
var fileName = string.Empty;
var validationCode = string.Empty;
var overwrite = false;
var isHostPortal = false;
var extract = false;
Expand Down Expand Up @@ -592,7 +607,9 @@ public Task<HttpResponseMessage> UploadFromLocal(int portalId)
int.TryParse(item.ReadAsStringAsync().Result, out portalId);
}
break;
case "\"VALIDATIONCODE\"":
validationCode = item.ReadAsStringAsync().Result ?? "";
break;
case "\"POSTFILE\"":
fileName = item.Headers.ContentDisposition.FileName.Replace("\"", "");
if (fileName.IndexOf("\\", StringComparison.Ordinal) != -1)
Expand All @@ -613,7 +630,7 @@ public Task<HttpResponseMessage> UploadFromLocal(int portalId)
currentSynchronizationContext.Send(
delegate
{
result = UploadFile(stream, portalId, userInfo, folder, filter, fileName, overwrite, isHostPortal, extract);
result = UploadFile(stream, portalId, userInfo, folder, filter, fileName, overwrite, isHostPortal, extract, validationCode);
},
null
);
Expand Down Expand Up @@ -680,7 +697,7 @@ public HttpResponseMessage UploadFromUrl(UploadByUrlDto dto)
}

result = UploadFile(responseStream, portalId, UserInfo, dto.Folder.ValueOrEmpty(), dto.Filter.ValueOrEmpty(),
fileName, dto.Overwrite, dto.IsHostMenu, dto.Unzip);
fileName, dto.Overwrite, dto.IsHostMenu, dto.Unzip, dto.ValidationCode);

/* Response Content Type cannot be application/json
* because IE9 with iframe-transport manages the response
Expand Down
18 changes: 18 additions & 0 deletions DNN Platform/DotNetNuke.Web/UI/WebControls/DnnFileUploadOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Globalization;
using System.Runtime.Serialization;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Portals;

namespace DotNetNuke.Web.UI.WebControls
{
Expand Down Expand Up @@ -141,6 +142,23 @@ public Dictionary<string, string> Parameters
[DataMember(Name = "folderPath")]
public string FolderPath;

[DataMember(Name = "validationCode")]
public string ValidationCode
{
get
{
var portalSettings = PortalSettings.Current;
var parameters = new List<object>(){Extensions};
if (portalSettings != null)
{
parameters.Add(portalSettings.PortalId);
parameters.Add(portalSettings.UserInfo.UserID);
}

return ValidationUtils.ComputeValidationCode(parameters);
}
}

public DnnFileUploadOptions()
{
FolderPicker = new DnnDropDownListOptions();
Expand Down
47 changes: 47 additions & 0 deletions DNN Platform/Library/Common/Utilities/ValidationUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotNetNuke.Entities.Host;
using DotNetNuke.Security;

namespace DotNetNuke.Common.Utilities
{
public sealed class ValidationUtils
{
internal static string GetDecryptionKey()
{
var machineKey = Config.GetDecryptionkey();
var key = $"{machineKey ?? ""}{Host.GUID.Replace("-", string.Empty)}";
return FIPSCompliant.EncryptAES(key, key, Host.GUID);
}

internal static string ComputeValidationCode(IList<object> parameters)
{
if (parameters != null && parameters.Any())
{
var checkString = string.Join("_", parameters.Select(p =>
{
if (p is IList<string> list)
{
return list.Select(i => i.ToLowerInvariant())
.OrderBy(i => i)
.Aggregate(string.Empty, (current, extension) => current.Append(extension, ", "));
}
return p.ToString();
}));

return PortalSecurity.Instance.Encrypt(GetDecryptionKey(), checkString);
}

return string.Empty;
}

internal static bool ValidationCodeMatched(IList<object> parameters, string validationCode)
{
return validationCode.Equals(ComputeValidationCode(parameters));
}
}
}
1 change: 1 addition & 0 deletions DNN Platform/Library/DotNetNuke.Library.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@
<Compile Include="Common\Utilities\CryptographyUtils.cs" />
<Compile Include="Common\Utilities\FileSystemExtensions.cs" />
<Compile Include="Common\Utilities\RegexUtils.cs" />
<Compile Include="Common\Utilities\ValidationUtils.cs" />
<Compile Include="Data\ControllerBase.cs" />
<Compile Include="Data\DatabaseConnectionProvider.cs" />
<Compile Include="Data\PetaPoco\FluentColumnMap.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,19 +147,12 @@ public void SaveProfile(PersonalizationInfo personalization, int userId, int por

private static string EncryptData(string profileData)
{
return PortalSecurity.Instance.Encrypt(GetDecryptionkey(), profileData);
return PortalSecurity.Instance.Encrypt(ValidationUtils.GetDecryptionKey(), profileData);
}

private static string DecryptData(string profileData)
{
return PortalSecurity.Instance.Decrypt(GetDecryptionkey(), profileData);
}

private static string GetDecryptionkey()
{
var machineKey = Config.GetDecryptionkey();
var key = $"{machineKey ?? ""}{Host.GUID.Replace("-", string.Empty)}";
return FIPSCompliant.EncryptAES(key, key, Host.GUID);
return PortalSecurity.Instance.Decrypt(ValidationUtils.GetDecryptionKey(), profileData);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,15 @@
success: $.proxy(this._onUploadByUrl, this, [status.fileName]),
error: $.onAjaxError
};
serviceSettings.data = { Url: status.fileName, Folder: this._selectedPath(), Overwrite: status.overwrite, Unzip: this._extract(), Filter: "", IsHostMenu: this.options.parameters.isHostPortal };
serviceSettings.data = {
Url: status.fileName,
Folder: this._selectedPath(),
Overwrite: status.overwrite,
Unzip: this._extract(),
Filter: this.options.extensions.join(","),
IsHostMenu: this.options.parameters.isHostPortal,
ValidationCode: this.options.validationCode
};
$.extend(serviceSettings.data, this.options.parameters);
$.ajax(serviceSettings);
},
Expand Down Expand Up @@ -437,9 +445,10 @@
var statusData = this._getFileUploadStatusElement(data.files[0].name).data("status");
data.formData = {
folder: this._selectedPath(),
filter: "",
filter: this.options.extensions.join(","),
extract: this._extract(),
overwrite: statusData.overwrite
overwrite: statusData.overwrite,
validationCode: this.options.validationCode
};
$.extend(data.formData, this.options.parameters);
return true;
Expand Down

0 comments on commit f6f6ef6

Please sign in to comment.