Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

validate file upload request. #3655

Merged
merged 2 commits into from
Apr 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,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 @@ -408,13 +409,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 @@ -575,6 +589,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 @@ -611,7 +626,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 @@ -632,7 +649,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 @@ -699,7 +716,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 @@ -2,6 +2,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 @@ -137,6 +138,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 @@ -192,6 +192,7 @@
<Compile Include="Common\NavigationManager.cs" />
<Compile Include="Common\Utilities\CryptographyUtils.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 @@ -163,19 +163,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 @@ -193,7 +193,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 @@ -439,9 +447,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