diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
index bf89c758aae4..2d1e7d9109f4 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
@@ -323,6 +323,7 @@
or click here to choose files
You can drag files here to upload
Cannot upload this file, it does not have an approved file type
+ Cannot upload this file, it does not have a valid file name
Max file size is
Media root
Failed to move media
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
index 79c113f99dbc..62c4b4f739f0 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
@@ -328,6 +328,7 @@
or click here to choose files
You can drag files here to upload.
Cannot upload this file, it does not have an approved file type
+ Cannot upload this file, it does not have a valid file name
Max file size is
Media root
Failed to move media
diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs
index c878d58e6cc3..62787fbedb94 100644
--- a/src/Umbraco.Web/Editors/ContentTypeController.cs
+++ b/src/Umbraco.Web/Editors/ContentTypeController.cs
@@ -576,43 +576,53 @@ public async Task Upload()
var fileName = file.Headers.ContentDisposition.FileName.Trim(Constants.CharArrays.DoubleQuote);
var ext = fileName.Substring(fileName.LastIndexOf('.') + 1).ToLower();
- var destFileName = root + "\\" + fileName;
- try
- {
- // due to a bug before 8.7.0 we didn't delete temp files, so we need to make sure to delete before
- // moving else you get errors and the upload fails without a message in the UI (there's a JS error)
- if(System.IO.File.Exists(destFileName))
- System.IO.File.Delete(destFileName);
-
- // renaming the file because MultipartFormDataStreamProvider has created a random fileName instead of using the name from the
- // content-disposition for more than 6 years now. Creating a CustomMultipartDataStreamProvider deriving from MultipartFormDataStreamProvider
- // seems like a cleaner option, but I'm not sure where to put it and renaming only takes one line of code.
- System.IO.File.Move(result.FileData[0].LocalFileName, destFileName);
- }
- catch (Exception ex)
+ var destFileName = Path.Combine(root, fileName);
+ if (Path.GetFullPath(destFileName).StartsWith(Path.GetFullPath(root)))
{
- Logger.Error(ex, "Error uploading udt file to App_Data: {File}", destFileName);
- }
-
- if (ext.InvariantEquals("udt"))
- {
- model.TempFileName = Path.Combine(root, fileName);
+ try
+ {
+ // due to a bug before 8.7.0 we didn't delete temp files, so we need to make sure to delete before
+ // moving else you get errors and the upload fails without a message in the UI (there's a JS error)
+ if(System.IO.File.Exists(destFileName))
+ System.IO.File.Delete(destFileName);
+
+ // renaming the file because MultipartFormDataStreamProvider has created a random fileName instead of using the name from the
+ // content-disposition for more than 6 years now. Creating a CustomMultipartDataStreamProvider deriving from MultipartFormDataStreamProvider
+ // seems like a cleaner option, but I'm not sure where to put it and renaming only takes one line of code.
+ System.IO.File.Move(result.FileData[0].LocalFileName, destFileName);
+ }
+ catch (Exception ex)
+ {
+ Logger.Error(ex, "Error uploading udt file to App_Data: {File}", destFileName);
+ }
- var xd = new XmlDocument
+ if (ext.InvariantEquals("udt"))
{
- XmlResolver = null
- };
- xd.Load(model.TempFileName);
+ model.TempFileName = destFileName;
+
+ var xd = new XmlDocument
+ {
+ XmlResolver = null
+ };
+ xd.Load(model.TempFileName);
- model.Alias = xd.DocumentElement?.SelectSingleNode("//DocumentType/Info/Alias")?.FirstChild.Value;
- model.Name = xd.DocumentElement?.SelectSingleNode("//DocumentType/Info/Name")?.FirstChild.Value;
+ model.Alias = xd.DocumentElement?.SelectSingleNode("//DocumentType/Info/Alias")?.FirstChild.Value;
+ model.Name = xd.DocumentElement?.SelectSingleNode("//DocumentType/Info/Name")?.FirstChild.Value;
+ }
+ else
+ {
+ model.Notifications.Add(new Notification(
+ Services.TextService.Localize("speechBubbles", "operationFailedHeader"),
+ Services.TextService.Localize("media", "disallowedFileType"),
+ NotificationStyle.Warning));
+ }
}
else
{
model.Notifications.Add(new Notification(
- Services.TextService.Localize("speechBubbles", "operationFailedHeader"),
- Services.TextService.Localize("media", "disallowedFileType"),
- NotificationStyle.Warning));
+ Services.TextService.Localize("speechBubbles", "operationFailedHeader"),
+ Services.TextService.Localize("media", "invalidFileName"),
+ NotificationStyle.Warning));
}
return model;