VYPR
Moderate severityNVD Advisory· Published May 21, 2024· Updated Aug 2, 2024

Umbraco CMS Vulnerable to Stored XSS on Content Page Through Markdown Editor Preview Pane

CVE-2024-35218

Description

Umbraco CMS is an ASP.NET CMS used by more than 730.000 websites. Stored Cross-site scripting (XSS) enable attackers that have access to backoffice to bring malicious content into a website or application. This vulnerability has been patched in version(s) 8.18.13, 10.8.4, 12.3.7, 13.1.1 by implementing IHtmlSanitizer.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
UmbracoCms.CoreNuGet
>= 8.0.0, < 8.18.138.18.13
UmbracoCms.CoreNuGet
>= 10.0.0, < 10.8.410.8.4
UmbracoCms.CoreNuGet
>= 12.0.0, < 12.3.712.3.7
UmbracoCms.CoreNuGet
>= 13.0.0, < 13.1.113.1.1

Affected products

1

Patches

4
1b712fe6ec52

Merge pull request from GHSA-gvpc-3pj6-4m9w

https://github.com/umbraco/Umbraco-CMSNikolaj GeisleFeb 6, 2024via ghsa
5 files changed · +71 1
  • src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs+2 1 modified
    @@ -317,8 +317,9 @@ private void AddCoreServices()
                 Services.AddSingleton<ConflictingPackageData>();
                 Services.AddSingleton<CompiledPackageXmlParser>();
     
    -            // Register a noop IHtmlSanitizer to be replaced
    +            // Register a noop IHtmlSanitizer & IMarkdownSanitizer to be replaced
                 Services.AddUnique<IHtmlSanitizer, NoopHtmlSanitizer>();
    +            Services.AddUnique<IMarkdownSanitizer, NoopMarkdownSanitizer>();
     
                 Services.AddUnique<IPropertyTypeUsageService, PropertyTypeUsageService>();
                 Services.AddUnique<IDataTypeUsageService, DataTypeUsageService>();
    
  • src/Umbraco.Core/PropertyEditors/MarkdownPropertyEditor.cs+8 0 modified
    @@ -4,6 +4,7 @@
     using Microsoft.Extensions.DependencyInjection;
     using Umbraco.Cms.Core.DependencyInjection;
     using Umbraco.Cms.Core.IO;
    +using Umbraco.Cms.Core.Models;
     using Umbraco.Cms.Core.Services;
     
     namespace Umbraco.Cms.Core.PropertyEditors;
    @@ -50,4 +51,11 @@ public MarkdownPropertyEditor(
         /// <inheritdoc />
         protected override IConfigurationEditor CreateConfigurationEditor() =>
             new MarkdownConfigurationEditor(_ioHelper, _editorConfigurationParser);
    +
    +    /// <summary>
    +    ///     Create a custom value editor
    +    /// </summary>
    +    /// <returns></returns>
    +    protected override IDataValueEditor CreateValueEditor() =>
    +        DataValueEditorFactory.Create<MarkDownPropertyValueEditor>(Attribute!);
     }
    
  • src/Umbraco.Core/PropertyEditors/MarkDownPropertyValueEditor.cs+39 0 added
    @@ -0,0 +1,39 @@
    +using Umbraco.Cms.Core.IO;
    +using Umbraco.Cms.Core.Models.Editors;
    +using Umbraco.Cms.Core.Security;
    +using Umbraco.Cms.Core.Serialization;
    +using Umbraco.Cms.Core.Services;
    +using Umbraco.Cms.Core.Strings;
    +using Umbraco.Extensions;
    +
    +namespace Umbraco.Cms.Core.PropertyEditors;
    +
    +/// <summary>
    +///     A custom value editor to ensure that macro syntax is parsed when being persisted and formatted correctly for
    +///     display in the editor
    +/// </summary>
    +internal class MarkDownPropertyValueEditor : DataValueEditor
    +{
    +    private readonly IMarkdownSanitizer _markdownSanitizer;
    +
    +    public MarkDownPropertyValueEditor(
    +        ILocalizedTextService localizedTextService,
    +        IShortStringHelper shortStringHelper,
    +        IJsonSerializer jsonSerializer,
    +        IIOHelper ioHelper,
    +        DataEditorAttribute attribute,
    +        IMarkdownSanitizer markdownSanitizer)
    +        : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute) => _markdownSanitizer = markdownSanitizer;
    +
    +    public override object? FromEditor(ContentPropertyData editorValue, object? currentValue)
    +    {
    +        if (string.IsNullOrWhiteSpace(editorValue.Value?.ToString()))
    +        {
    +            return null;
    +        }
    +
    +        var sanitized = _markdownSanitizer.Sanitize(editorValue.Value.ToString()!);
    +
    +        return sanitized.NullOrWhiteSpaceAsNull();
    +    }
    +}
    
  • src/Umbraco.Core/Security/IMarkdownSanitizer.cs+14 0 added
    @@ -0,0 +1,14 @@
    +namespace Umbraco.Cms.Core.Security;
    +
    +/// <summary>
    +/// Sanitizer service for the markdown editor.
    +/// </summary>
    +public interface IMarkdownSanitizer
    +{
    +    /// <summary>
    +    ///     Sanitizes Markdown
    +    /// </summary>
    +    /// <param name="markdown">Markdown to be sanitized</param>
    +    /// <returns>Sanitized Markdown</returns>
    +    string Sanitize(string markdown);
    +}
    
  • src/Umbraco.Core/Security/NoopMarkdownSanitizer.cs+8 0 added
    @@ -0,0 +1,8 @@
    +namespace Umbraco.Cms.Core.Security;
    +
    +/// <inheritdoc />
    +public class NoopMarkdownSanitizer : IMarkdownSanitizer
    +{
    +    /// <inheritdoc />
    +    public string Sanitize(string markdown) => markdown;
    +}
    
a2684069b1e9

Merge pull request from GHSA-gvpc-3pj6-4m9w

https://github.com/umbraco/Umbraco-CMSNikolaj GeisleFeb 6, 2024via ghsa
7 files changed · +70 2
  • src/Umbraco.Core/Composing/CompositionExtensions/Services.cs+1 0 modified
    @@ -83,6 +83,7 @@ public static Composition ComposeServices(this Composition composition)
     
                 composition.RegisterUnique<ITelemetryService, TelemetryService>();
                 composition.RegisterUnique<IHtmlSanitizer, NoopHtmlSanitizer>();
    +            composition.RegisterUnique<IMarkdownSanitizer, NoopMarkdownSanitizer>();
                 composition.RegisterUnique<IFileStreamSecurityValidator, FileStreamSecurityValidator>();
     
                 return composition;
    
  • src/Umbraco.Core/Security/IMarkdownSanitizer.cs+14 0 added
    @@ -0,0 +1,14 @@
    +namespace Umbraco.Core.Security
    +{
    +   public interface IMarkdownSanitizer
    +   {
    +       /// <summary>
    +       /// Sanitizes Markdown
    +       /// </summary>
    +       /// <param name="markdown">Markdown to be sanitized</param>
    +       /// <returns>Sanitized Markdown</returns>
    +       string Sanitize(string markdown);
    +   }
    +}
    +
    +
    
  • src/Umbraco.Core/Security/NoopMarkdownSanitizer.cs+10 0 added
    @@ -0,0 +1,10 @@
    +namespace Umbraco.Core.Security
    +{
    +    public class NoopMarkdownSanitizer : IMarkdownSanitizer
    +    {
    +        public string Sanitize(string markdown)
    +        {
    +            return markdown;
    +        }
    +    }
    +}
    
  • src/Umbraco.Core/Umbraco.Core.csproj+2 0 modified
    @@ -201,7 +201,9 @@
         <Compile Include="Security\IFileStreamSecurityAnalyzer.cs" />
         <Compile Include="Security\IFileStreamSecurityValidator.cs" />
         <Compile Include="Security\IHtmlSanitizer.cs" />
    +    <Compile Include="Security\IMarkdownSanitizer.cs" />
         <Compile Include="Security\NoopHtmlSanitizer.cs" />
    +    <Compile Include="Security\NoopMarkdownSanitizer.cs" />
         <Compile Include="Serialization\AutoInterningStringConverter.cs" />
         <Compile Include="Serialization\AutoInterningStringKeyCaseInsensitiveDictionaryConverter.cs" />
         <Compile Include="PropertyEditors\EyeDropperColorPickerConfiguration.cs" />
    
  • src/Umbraco.Web/PropertyEditors/MarkdownPropertyEditor.cs+13 2 modified
    @@ -1,6 +1,7 @@
     using Umbraco.Core;
     using Umbraco.Core.Logging;
     using Umbraco.Core.PropertyEditors;
    +using Umbraco.Core.Security;
     
     namespace Umbraco.Web.PropertyEditors
     {
    @@ -16,14 +17,24 @@ namespace Umbraco.Web.PropertyEditors
             Icon = "icon-code")]
         public class MarkdownPropertyEditor : DataEditor
         {
    +        private readonly IMarkdownSanitizer _markdownSanitizer;
    +
             /// <summary>
             /// Initializes a new instance of the <see cref="MarkdownPropertyEditor"/> class.
             /// </summary>
    -        public MarkdownPropertyEditor(ILogger logger)
    +        public MarkdownPropertyEditor(ILogger logger, IMarkdownSanitizer markdownSanitizer)
                 : base(logger)
    -        { }
    +        {
    +            _markdownSanitizer = markdownSanitizer;
    +        }
     
             /// <inheritdoc />
             protected override IConfigurationEditor CreateConfigurationEditor() => new MarkdownConfigurationEditor();
    +
    +        /// <summary>
    +        ///     Create a custom value editor
    +        /// </summary>
    +        /// <returns></returns>
    +        protected override IDataValueEditor CreateValueEditor() => new MarkDownPropertyValueEditor(Attribute, _markdownSanitizer);
         }
     }
    
  • src/Umbraco.Web/PropertyEditors/MarkDownPropertyValueEditor.cs+29 0 added
    @@ -0,0 +1,29 @@
    +using Umbraco.Core;
    +using Umbraco.Core.Models.Editors;
    +using Umbraco.Core.PropertyEditors;
    +using Umbraco.Core.Security;
    +
    +namespace Umbraco.Web.PropertyEditors;
    +
    +internal class MarkDownPropertyValueEditor : DataValueEditor
    +{
    +    private readonly IMarkdownSanitizer _markdownSanitizer;
    +
    +    public MarkDownPropertyValueEditor(DataEditorAttribute attribute, IMarkdownSanitizer markdownSanitizer) : base(attribute)
    +    {
    +        _markdownSanitizer = markdownSanitizer;
    +    }
    +
    +    public override object FromEditor(ContentPropertyData editorValue, object currentValue)
    +    {
    +        var editorValueString = editorValue.Value?.ToString();
    +        if (string.IsNullOrWhiteSpace(editorValueString))
    +        {
    +            return null;
    +        }
    +
    +        var sanitized = _markdownSanitizer.Sanitize(editorValueString);
    +
    +        return sanitized.NullOrWhiteSpaceAsNull();
    +    }
    +}
    
  • src/Umbraco.Web/Umbraco.Web.csproj+1 0 modified
    @@ -288,6 +288,7 @@
         <Compile Include="PropertyEditors\ComplexEditorValidator.cs" />
         <Compile Include="PropertyEditors\FileUploadConfiguration.cs" />
         <Compile Include="PropertyEditors\FileUploadConfigurationEditor.cs" />
    +    <Compile Include="PropertyEditors\MarkDownPropertyValueEditor.cs" />
         <Compile Include="PropertyEditors\MediaPicker3Configuration.cs" />
         <Compile Include="PropertyEditors\MediaPicker3ConfigurationEditor.cs" />
         <Compile Include="PropertyEditors\MediaPicker3PropertyEditor.cs" />
    
cbf9f9bcd199

Merge pull request from GHSA-gvpc-3pj6-4m9w

https://github.com/umbraco/Umbraco-CMSNikolaj GeisleFeb 6, 2024via ghsa
5 files changed · +71 1
  • src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs+2 1 modified
    @@ -318,8 +318,9 @@ private void AddCoreServices()
                 Services.AddSingleton<ConflictingPackageData>();
                 Services.AddSingleton<CompiledPackageXmlParser>();
     
    -            // Register a noop IHtmlSanitizer to be replaced
    +            // Register a noop IHtmlSanitizer & IMarkdownSanitizer to be replaced
                 Services.AddUnique<IHtmlSanitizer, NoopHtmlSanitizer>();
    +            Services.AddUnique<IMarkdownSanitizer, NoopMarkdownSanitizer>();
     
                 Services.AddUnique<IPropertyTypeUsageService, PropertyTypeUsageService>();
                 Services.AddUnique<IDataTypeUsageService, DataTypeUsageService>();
    
  • src/Umbraco.Core/PropertyEditors/MarkdownPropertyEditor.cs+8 0 modified
    @@ -3,6 +3,7 @@
     
     using Microsoft.Extensions.DependencyInjection;
     using Umbraco.Cms.Core.IO;
    +using Umbraco.Cms.Core.Models;
     using Umbraco.Cms.Core.Services;
     using Umbraco.Cms.Web.Common.DependencyInjection;
     
    @@ -50,4 +51,11 @@ public MarkdownPropertyEditor(
         /// <inheritdoc />
         protected override IConfigurationEditor CreateConfigurationEditor() =>
             new MarkdownConfigurationEditor(_ioHelper, _editorConfigurationParser);
    +
    +    /// <summary>
    +    ///     Create a custom value editor
    +    /// </summary>
    +    /// <returns></returns>
    +    protected override IDataValueEditor CreateValueEditor() =>
    +        DataValueEditorFactory.Create<MarkDownPropertyValueEditor>(Attribute!);
     }
    
  • src/Umbraco.Core/PropertyEditors/MarkDownPropertyValueEditor.cs+39 0 added
    @@ -0,0 +1,39 @@
    +using Umbraco.Cms.Core.IO;
    +using Umbraco.Cms.Core.Models.Editors;
    +using Umbraco.Cms.Core.Security;
    +using Umbraco.Cms.Core.Serialization;
    +using Umbraco.Cms.Core.Services;
    +using Umbraco.Cms.Core.Strings;
    +using Umbraco.Extensions;
    +
    +namespace Umbraco.Cms.Core.PropertyEditors;
    +
    +/// <summary>
    +///     A custom value editor to ensure that macro syntax is parsed when being persisted and formatted correctly for
    +///     display in the editor
    +/// </summary>
    +internal class MarkDownPropertyValueEditor : DataValueEditor
    +{
    +    private readonly IMarkdownSanitizer _markdownSanitizer;
    +
    +    public MarkDownPropertyValueEditor(
    +        ILocalizedTextService localizedTextService,
    +        IShortStringHelper shortStringHelper,
    +        IJsonSerializer jsonSerializer,
    +        IIOHelper ioHelper,
    +        DataEditorAttribute attribute,
    +        IMarkdownSanitizer markdownSanitizer)
    +        : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute) => _markdownSanitizer = markdownSanitizer;
    +
    +    public override object? FromEditor(ContentPropertyData editorValue, object? currentValue)
    +    {
    +        if (string.IsNullOrWhiteSpace(editorValue.Value?.ToString()))
    +        {
    +            return null;
    +        }
    +
    +        var sanitized = _markdownSanitizer.Sanitize(editorValue.Value.ToString()!);
    +
    +        return sanitized.NullOrWhiteSpaceAsNull();
    +    }
    +}
    
  • src/Umbraco.Core/Security/IMarkdownSanitizer.cs+14 0 added
    @@ -0,0 +1,14 @@
    +namespace Umbraco.Cms.Core.Security;
    +
    +/// <summary>
    +/// Sanitizer service for the markdown editor.
    +/// </summary>
    +public interface IMarkdownSanitizer
    +{
    +    /// <summary>
    +    ///     Sanitizes Markdown
    +    /// </summary>
    +    /// <param name="markdown">Markdown to be sanitized</param>
    +    /// <returns>Sanitized Markdown</returns>
    +    string Sanitize(string markdown);
    +}
    
  • src/Umbraco.Core/Security/NoopMarkdownSanitizer.cs+8 0 added
    @@ -0,0 +1,8 @@
    +namespace Umbraco.Cms.Core.Security;
    +
    +/// <inheritdoc />
    +public class NoopMarkdownSanitizer : IMarkdownSanitizer
    +{
    +    /// <inheritdoc />
    +    public string Sanitize(string markdown) => markdown;
    +}
    
d090176272d0

Merge pull request from GHSA-gvpc-3pj6-4m9w

https://github.com/umbraco/Umbraco-CMSNikolaj GeisleFeb 6, 2024via ghsa
5 files changed · +71 1
  • src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs+2 1 modified
    @@ -317,8 +317,9 @@ private void AddCoreServices()
                 Services.AddSingleton<ConflictingPackageData>();
                 Services.AddSingleton<CompiledPackageXmlParser>();
     
    -            // Register a noop IHtmlSanitizer to be replaced
    +            // Register a noop IHtmlSanitizer & IMarkdownSanitizer to be replaced
                 Services.AddUnique<IHtmlSanitizer, NoopHtmlSanitizer>();
    +            Services.AddUnique<IMarkdownSanitizer, NoopMarkdownSanitizer>();
     
                 Services.AddUnique<IPropertyTypeUsageService, PropertyTypeUsageService>();
                 Services.AddUnique<IDataTypeUsageService, DataTypeUsageService>();
    
  • src/Umbraco.Core/PropertyEditors/MarkdownPropertyEditor.cs+8 0 modified
    @@ -4,6 +4,7 @@
     using Microsoft.Extensions.DependencyInjection;
     using Umbraco.Cms.Core.DependencyInjection;
     using Umbraco.Cms.Core.IO;
    +using Umbraco.Cms.Core.Models;
     using Umbraco.Cms.Core.Services;
     
     namespace Umbraco.Cms.Core.PropertyEditors;
    @@ -50,4 +51,11 @@ public MarkdownPropertyEditor(
         /// <inheritdoc />
         protected override IConfigurationEditor CreateConfigurationEditor() =>
             new MarkdownConfigurationEditor(_ioHelper, _editorConfigurationParser);
    +
    +    /// <summary>
    +    ///     Create a custom value editor
    +    /// </summary>
    +    /// <returns></returns>
    +    protected override IDataValueEditor CreateValueEditor() =>
    +        DataValueEditorFactory.Create<MarkDownPropertyValueEditor>(Attribute!);
     }
    
  • src/Umbraco.Core/PropertyEditors/MarkDownPropertyValueEditor.cs+39 0 added
    @@ -0,0 +1,39 @@
    +using Umbraco.Cms.Core.IO;
    +using Umbraco.Cms.Core.Models.Editors;
    +using Umbraco.Cms.Core.Security;
    +using Umbraco.Cms.Core.Serialization;
    +using Umbraco.Cms.Core.Services;
    +using Umbraco.Cms.Core.Strings;
    +using Umbraco.Extensions;
    +
    +namespace Umbraco.Cms.Core.PropertyEditors;
    +
    +/// <summary>
    +///     A custom value editor to ensure that macro syntax is parsed when being persisted and formatted correctly for
    +///     display in the editor
    +/// </summary>
    +internal class MarkDownPropertyValueEditor : DataValueEditor
    +{
    +    private readonly IMarkdownSanitizer _markdownSanitizer;
    +
    +    public MarkDownPropertyValueEditor(
    +        ILocalizedTextService localizedTextService,
    +        IShortStringHelper shortStringHelper,
    +        IJsonSerializer jsonSerializer,
    +        IIOHelper ioHelper,
    +        DataEditorAttribute attribute,
    +        IMarkdownSanitizer markdownSanitizer)
    +        : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute) => _markdownSanitizer = markdownSanitizer;
    +
    +    public override object? FromEditor(ContentPropertyData editorValue, object? currentValue)
    +    {
    +        if (string.IsNullOrWhiteSpace(editorValue.Value?.ToString()))
    +        {
    +            return null;
    +        }
    +
    +        var sanitized = _markdownSanitizer.Sanitize(editorValue.Value.ToString()!);
    +
    +        return sanitized.NullOrWhiteSpaceAsNull();
    +    }
    +}
    
  • src/Umbraco.Core/Security/IMarkdownSanitizer.cs+14 0 added
    @@ -0,0 +1,14 @@
    +namespace Umbraco.Cms.Core.Security;
    +
    +/// <summary>
    +/// Sanitizer service for the markdown editor.
    +/// </summary>
    +public interface IMarkdownSanitizer
    +{
    +    /// <summary>
    +    ///     Sanitizes Markdown
    +    /// </summary>
    +    /// <param name="markdown">Markdown to be sanitized</param>
    +    /// <returns>Sanitized Markdown</returns>
    +    string Sanitize(string markdown);
    +}
    
  • src/Umbraco.Core/Security/NoopMarkdownSanitizer.cs+8 0 added
    @@ -0,0 +1,8 @@
    +namespace Umbraco.Cms.Core.Security;
    +
    +/// <inheritdoc />
    +public class NoopMarkdownSanitizer : IMarkdownSanitizer
    +{
    +    /// <inheritdoc />
    +    public string Sanitize(string markdown) => markdown;
    +}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.