validate folder names, handle missing files more gracefully

This commit is contained in:
Shaun Walker 2020-05-12 13:24:51 -04:00
parent c83496d814
commit 6f3fe8d933
7 changed files with 99 additions and 30 deletions

View File

@ -149,10 +149,16 @@
{ {
folder = await FolderService.AddFolderAsync(folder); folder = await FolderService.AddFolderAsync(folder);
} }
if (folder != null)
await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId); {
await logger.LogInformation("Folder Saved {Folder}", folder); await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId);
NavigationManager.NavigateTo(NavigateUrl()); await logger.LogInformation("Folder Saved {Folder}", folder);
NavigationManager.NavigateTo(NavigateUrl());
}
else
{
AddModuleMessage("An Error Was Encountered Saving The Folder", MessageType.Error);
}
} }
else else
{ {

View File

@ -16,6 +16,7 @@ using System.Net;
using Oqtane.Enums; using Oqtane.Enums;
using Oqtane.Infrastructure; using Oqtane.Infrastructure;
using Oqtane.Repository; using Oqtane.Repository;
using Microsoft.AspNetCore.Routing.Constraints;
// ReSharper disable StringIndexOfIsCultureSpecific.1 // ReSharper disable StringIndexOfIsCultureSpecific.1
@ -396,12 +397,13 @@ namespace Oqtane.Controllers
[HttpGet("download/{id}")] [HttpGet("download/{id}")]
public IActionResult Download(int id) public IActionResult Download(int id)
{ {
string errorpath = Path.Combine(GetFolderPath("images"), "error.png");
Models.File file = _files.GetFile(id); Models.File file = _files.GetFile(id);
if (file != null) if (file != null)
{ {
if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions)) if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
{ {
string filepath = Path.Combine(GetFolderPath(file.Folder) , file.Name); string filepath = Path.Combine(GetFolderPath(file.Folder), file.Name);
if (System.IO.File.Exists(filepath)) if (System.IO.File.Exists(filepath))
{ {
byte[] filebytes = System.IO.File.ReadAllBytes(filepath); byte[] filebytes = System.IO.File.ReadAllBytes(filepath);
@ -411,21 +413,24 @@ namespace Oqtane.Controllers
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {FileId} {FilePath}", id, filepath); _logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {FileId} {FilePath}", id, filepath);
HttpContext.Response.StatusCode = 404; HttpContext.Response.StatusCode = 404;
return null; byte[] filebytes = System.IO.File.ReadAllBytes(errorpath);
return File(filebytes, "application/octet-stream", file.Name);
} }
} }
else else
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {FileId}", id); _logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {FileId}", id);
HttpContext.Response.StatusCode = 401; HttpContext.Response.StatusCode = 401;
return null; byte[] filebytes = System.IO.File.ReadAllBytes(errorpath);
return File(filebytes, "application/octet-stream", file.Name);
} }
} }
else else
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Not Found {FileId}", id); _logger.Log(LogLevel.Error, this, LogFunction.Read, "File Not Found {FileId}", id);
HttpContext.Response.StatusCode = 404; HttpContext.Response.StatusCode = 404;
return null; byte[] filebytes = System.IO.File.ReadAllBytes(errorpath);
return File(filebytes, "application/octet-stream", "error.png");
} }
} }

View File

@ -10,7 +10,6 @@ using Oqtane.Extensions;
using Oqtane.Infrastructure; using Oqtane.Infrastructure;
using Oqtane.Repository; using Oqtane.Repository;
using Oqtane.Security; using Oqtane.Security;
using System.IO;
namespace Oqtane.Controllers namespace Oqtane.Controllers
{ {
@ -106,13 +105,23 @@ namespace Oqtane.Controllers
} }
if (_userPermissions.IsAuthorized(User,PermissionNames.Edit, permissions)) if (_userPermissions.IsAuthorized(User,PermissionNames.Edit, permissions))
{ {
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null) if (FolderPathValid(folder))
{ {
Folder parent = _folders.GetFolder(folder.ParentId.Value); if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
folder.Path = Utilities.PathCombine(parent.Path, folder.Name,"\\"); {
Folder parent = _folders.GetFolder(folder.ParentId.Value);
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
}
folder.Path = Utilities.PathCombine(folder.Path, "\\");
folder = _folders.AddFolder(folder);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", folder);
}
else
{
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Name Not Valid {Folder}", folder);
HttpContext.Response.StatusCode = 401;
folder = null;
} }
folder = _folders.AddFolder(folder);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", folder);
} }
else else
{ {
@ -131,13 +140,23 @@ namespace Oqtane.Controllers
{ {
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Folder, folder.FolderId, PermissionNames.Edit)) if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Folder, folder.FolderId, PermissionNames.Edit))
{ {
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null) if (FolderPathValid(folder))
{ {
Folder parent = _folders.GetFolder(folder.ParentId.Value); if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
folder.Path = Utilities.PathCombine(parent.Path, folder.Name,"\\"); {
Folder parent = _folders.GetFolder(folder.ParentId.Value);
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
}
folder.Path = Utilities.PathCombine(folder.Path, "\\");
folder = _folders.UpdateFolder(folder);
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", folder);
}
else
{
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Name Not Valid {Folder}", folder);
HttpContext.Response.StatusCode = 401;
folder = null;
} }
folder = _folders.UpdateFolder(folder);
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", folder);
} }
else else
{ {
@ -191,5 +210,11 @@ namespace Oqtane.Controllers
HttpContext.Response.StatusCode = 401; HttpContext.Response.StatusCode = 401;
} }
} }
private bool FolderPathValid(Folder folder)
{
// prevent folder path traversal and reserved devices
return (!folder.Name.Contains("\\") && !folder.Name.Contains("/") && !Constants.ReservedDevices.Split(',').Contains(folder.Name.ToUpper()));
}
} }
} }

View File

@ -101,6 +101,12 @@
flex-direction: row; flex-direction: row;
} }
.app-logo {
display: block;
margin-left: auto;
margin-right: auto;
}
.breadcrumbs { .breadcrumbs {
position: fixed; position: fixed;
left: 275px; left: 275px;
@ -164,6 +170,12 @@
} }
@media (max-width: 767px) { @media (max-width: 767px) {
.app-logo {
height: 80px;
display: flex;
align-items: center;
}
.breadcrumbs { .breadcrumbs {
position: fixed; position: fixed;
top: 150px; top: 150px;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -81,14 +81,26 @@ window.interop = {
if (link.href !== url) { if (link.href !== url) {
link.setAttribute('href', url); link.setAttribute('href', url);
} }
if (type !== "" && link.type !== type) { if (type !== "") {
link.setAttribute('type', type); if (link.type !== type) {
link.setAttribute('type', type);
}
} else {
link.removeAttribute('type');
} }
if (integrity !== "" && link.integrity !== integrity) { if (integrity !== "") {
link.setAttribute('integrity', integrity); if (link.integrity !== integrity) {
link.setAttribute('integrity', integrity);
}
} else {
link.removeAttribute('integrity');
} }
if (crossorigin !== "" && link.crossOrigin !== crossorigin) { if (crossorigin !== "") {
link.setAttribute('crossorigin', crossorigin); if (link.crossOrigin !== crossorigin) {
link.setAttribute('crossorigin', crossorigin);
}
} else {
link.removeAttribute('crossorigin');
} }
} }
}, },
@ -126,11 +138,19 @@ window.interop = {
if (script.src !== src) { if (script.src !== src) {
script.src = src; script.src = src;
} }
if (integrity !== "" && script.integrity !== integrity) { if (integrity !== "") {
script.setAttribute('integrity', integrity); if (script.integrity !== integrity) {
script.setAttribute('integrity', integrity);
}
} else {
script.removeAttribute('integrity');
} }
if (crossorigin !== "" && script.crossorigin !== crossorigin) { if (crossorigin !== "") {
script.setAttribute('crossorigin', crossorigin); if (script.crossOrigin !== crossorigin) {
script.setAttribute('crossorigin', crossorigin);
}
} else {
script.removeAttribute('crossorigin');
} }
} }
else { else {

View File

@ -43,5 +43,6 @@
public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png"; public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png";
public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg"; public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg";
public const string ReservedDevices = "CON,NUL,PRN,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9";
} }
} }