Merge pull request #4512 from sbwalker/dev
improve file name and extension validation
This commit is contained in:
commit
bb55644c06
|
@ -171,18 +171,27 @@ namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
if (_userPermissions.IsAuthorized(User, folder.SiteId, EntityNames.Folder, file.FolderId, PermissionNames.Edit))
|
if (_userPermissions.IsAuthorized(User, folder.SiteId, EntityNames.Folder, file.FolderId, PermissionNames.Edit))
|
||||||
{
|
{
|
||||||
var filepath = _files.GetFilePath(file);
|
if (HasValidFileExtension(file.Name) && file.Name.IsPathOrFileValid())
|
||||||
if (System.IO.File.Exists(filepath))
|
|
||||||
{
|
{
|
||||||
file = CreateFile(file.Name, folder.FolderId, filepath);
|
var filepath = _files.GetFilePath(file);
|
||||||
file = _files.AddFile(file);
|
if (System.IO.File.Exists(filepath))
|
||||||
_syncManager.AddSyncEvent(_alias, EntityNames.File, file.FileId, SyncEventActions.Create);
|
{
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "File Added {File}", file);
|
file = CreateFile(file.Name, folder.FolderId, filepath);
|
||||||
|
file = _files.AddFile(file);
|
||||||
|
_syncManager.AddSyncEvent(_alias, EntityNames.File, file.FileId, SyncEventActions.Create);
|
||||||
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "File Added {File}", file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "File Does Not Exist At Path {FilePath}", filepath);
|
||||||
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||||
|
file = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "File Does Not Exist At Path {FilePath}", filepath);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "File Name Is Invalid Or Contains Invalid Extension {File}", file.Name);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
file = null;
|
file = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,29 +222,38 @@ namespace Oqtane.Controllers
|
||||||
&& _userPermissions.IsAuthorized(User, file.Folder.SiteId, EntityNames.Folder, File.FolderId, PermissionNames.Edit) // ensure user had edit rights to original folder
|
&& _userPermissions.IsAuthorized(User, file.Folder.SiteId, EntityNames.Folder, File.FolderId, PermissionNames.Edit) // ensure user had edit rights to original folder
|
||||||
&& _userPermissions.IsAuthorized(User, file.Folder.SiteId, EntityNames.Folder, file.FolderId, PermissionNames.Edit)) // ensure user has edit rights to new folder
|
&& _userPermissions.IsAuthorized(User, file.Folder.SiteId, EntityNames.Folder, file.FolderId, PermissionNames.Edit)) // ensure user has edit rights to new folder
|
||||||
{
|
{
|
||||||
if (File.Name != file.Name || File.FolderId != file.FolderId)
|
if (HasValidFileExtension(file.Name) && file.Name.IsPathOrFileValid())
|
||||||
{
|
{
|
||||||
file.Folder = _folders.GetFolder(file.FolderId, false);
|
if (File.Name != file.Name || File.FolderId != file.FolderId)
|
||||||
string folderpath = _folders.GetFolderPath(file.Folder);
|
|
||||||
if (!Directory.Exists(folderpath))
|
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(folderpath);
|
file.Folder = _folders.GetFolder(file.FolderId, false);
|
||||||
|
string folderpath = _folders.GetFolderPath(file.Folder);
|
||||||
|
if (!Directory.Exists(folderpath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(folderpath);
|
||||||
|
}
|
||||||
|
System.IO.File.Move(_files.GetFilePath(File), Path.Combine(folderpath, file.Name));
|
||||||
}
|
}
|
||||||
System.IO.File.Move(_files.GetFilePath(File), Path.Combine(folderpath, file.Name));
|
|
||||||
}
|
|
||||||
|
|
||||||
var newfile = CreateFile(File.Name, file.Folder.FolderId, _files.GetFilePath(file));
|
var newfile = CreateFile(File.Name, file.Folder.FolderId, _files.GetFilePath(file));
|
||||||
if (newfile != null)
|
if (newfile != null)
|
||||||
|
{
|
||||||
|
file.Extension = newfile.Extension;
|
||||||
|
file.Size = newfile.Size;
|
||||||
|
file.ImageWidth = newfile.ImageWidth;
|
||||||
|
file.ImageHeight = newfile.ImageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
file = _files.UpdateFile(file);
|
||||||
|
_syncManager.AddSyncEvent(_alias, EntityNames.File, file.FileId, SyncEventActions.Update);
|
||||||
|
_logger.Log(LogLevel.Information, this, LogFunction.Update, "File Updated {File}", file);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
file.Extension = newfile.Extension;
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "File Name Is Invalid Or Contains Invalid Extension {File}", file.Name);
|
||||||
file.Size = newfile.Size;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
file.ImageWidth = newfile.ImageWidth;
|
file = null;
|
||||||
file.ImageHeight = newfile.ImageHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file = _files.UpdateFile(file);
|
|
||||||
_syncManager.AddSyncEvent(_alias, EntityNames.File, file.FileId, SyncEventActions.Update);
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "File Updated {File}", file);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -289,64 +307,54 @@ namespace Oqtane.Controllers
|
||||||
folder = _folders.GetFolder(FolderId);
|
folder = _folders.GetFolder(FolderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
var _UploadableFiles = _settingRepository.GetSetting(EntityNames.Site, _alias.SiteId, "UploadableFiles")?.SettingValue;
|
|
||||||
_UploadableFiles = (string.IsNullOrEmpty(_UploadableFiles)) ? Constants.UploadableFiles : _UploadableFiles;
|
|
||||||
|
|
||||||
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Edit, folder.PermissionList))
|
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Edit, folder.PermissionList))
|
||||||
{
|
{
|
||||||
string folderPath = _folders.GetFolderPath(folder);
|
|
||||||
CreateDirectory(folderPath);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(name))
|
if (string.IsNullOrEmpty(name))
|
||||||
{
|
{
|
||||||
name = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal) + 1);
|
name = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal) + 1);
|
||||||
}
|
}
|
||||||
// check for allowable file extensions
|
|
||||||
if (!_UploadableFiles.Split(',').Contains(Path.GetExtension(name).ToLower().Replace(".", "")))
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, "File Could Not Be Downloaded From Url Due To Its File Extension {Url}", url);
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name.IsPathOrFileValid())
|
if (HasValidFileExtension(name) && name.IsPathOrFileValid())
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, $"File Could Not Be Downloaded From Url Due To Its File Name Not Allowed {url}");
|
try
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string targetPath = Path.Combine(folderPath, name);
|
|
||||||
|
|
||||||
// remove file if it already exists
|
|
||||||
if (System.IO.File.Exists(targetPath))
|
|
||||||
{
|
{
|
||||||
System.IO.File.Delete(targetPath);
|
string folderPath = _folders.GetFolderPath(folder);
|
||||||
}
|
CreateDirectory(folderPath);
|
||||||
|
|
||||||
using (var client = new HttpClient())
|
string targetPath = Path.Combine(folderPath, name);
|
||||||
{
|
if (System.IO.File.Exists(targetPath))
|
||||||
using (var stream = await client.GetStreamAsync(url))
|
|
||||||
{
|
{
|
||||||
using (var fileStream = new FileStream(targetPath, FileMode.CreateNew))
|
System.IO.File.Delete(targetPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
using (var stream = await client.GetStreamAsync(url))
|
||||||
{
|
{
|
||||||
await stream.CopyToAsync(fileStream);
|
using (var fileStream = new FileStream(targetPath, FileMode.CreateNew))
|
||||||
|
{
|
||||||
|
await stream.CopyToAsync(fileStream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
file = CreateFile(name, folder.FolderId, targetPath);
|
file = CreateFile(name, folder.FolderId, targetPath);
|
||||||
if (file != null)
|
if (file != null)
|
||||||
|
{
|
||||||
|
file = _files.AddFile(file);
|
||||||
|
_syncManager.AddSyncEvent(_alias, EntityNames.File, file.FileId, SyncEventActions.Create);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
file = _files.AddFile(file);
|
_logger.Log(LogLevel.Error, this, LogFunction.Create, ex, "File Could Not Be Downloaded From Url {Url} {Error}", url, ex.Message);
|
||||||
_syncManager.AddSyncEvent(_alias, EntityNames.File, file.FileId, SyncEventActions.Create);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, ex, "File Could Not Be Downloaded From Url {Url} {Error}", url, ex.Message);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "File Name Is Invalid Or Contains Invalid Extension {File}", name);
|
||||||
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
file = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -368,21 +376,11 @@ namespace Oqtane.Controllers
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the UploadableFiles extensions
|
|
||||||
string _UploadableFiles = _settingRepository.GetSetting(EntityNames.Site, _alias.SiteId, "UploadableFiles")?.SettingValue;
|
|
||||||
_UploadableFiles = (string.IsNullOrEmpty(_UploadableFiles)) ? Constants.UploadableFiles : _UploadableFiles;
|
|
||||||
|
|
||||||
// ensure filename is valid
|
// ensure filename is valid
|
||||||
string token = ".part_";
|
string token = ".part_";
|
||||||
if (!formfile.FileName.IsPathOrFileValid() || !formfile.FileName.Contains(token))
|
if (!formfile.FileName.IsPathOrFileValid() || !formfile.FileName.Contains(token) || !HasValidFileExtension(formfile.FileName.Substring(0, formfile.FileName.IndexOf(token))))
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for allowable file extensions (ignore token)
|
|
||||||
var extension = Path.GetExtension(formfile.FileName.Substring(0, formfile.FileName.IndexOf(token))).Replace(".", "");
|
|
||||||
if (!_UploadableFiles.Split(',').Contains(extension.ToLower()))
|
|
||||||
{
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "File Name Is Invalid Or Contains Invalid Extension {File}", formfile.FileName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,5 +841,12 @@ namespace Oqtane.Controllers
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool HasValidFileExtension(string fileName)
|
||||||
|
{
|
||||||
|
var _uploadableFiles = _settingRepository.GetSetting(EntityNames.Site, _alias.SiteId, "UploadableFiles")?.SettingValue;
|
||||||
|
_uploadableFiles = (string.IsNullOrEmpty(_uploadableFiles)) ? Constants.UploadableFiles : _uploadableFiles;
|
||||||
|
return _uploadableFiles.Split(',').Contains(Path.GetExtension(fileName).ToLower().Replace(".", ""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user