Vulnerability: Cross-site Scripting in ZKEACMS A cross-site scripting (XSS) vulnerability in /navigation/create?ParentID=%23 of ZKEACMS v3.5.2 allows attackers to execute arbitrary web scripts or HTML via a crafted payload injected into the ParentID parameter.
Vulnerability ID: GHSA-hc72-vj3g-5g2g
CWE: CWE-79
Severity score: 5.4
Project: https://github.com/SeriaWei/ZKEACMS
Published: 2022-05-26
File: src/ZKEACMS/Common/Service/NavigationService.cs
Commit message: Sanitize Html

#457
Commit author: wayne

Vulnerable version (before fix):
 using ZKEACMS.Common.Models; using Easy; using Microsoft.EntityFrameworkCore;  namespace ZKEACMS.Common.Service {     public class NavigationService : ServiceBase<NavigationEntity, CMSDbContext>, INavigationService     {         public NavigationService(IApplicationContext applicationContext, CMSDbContext dbContext) : base(applicationContext, dbContext)         {         }         public override DbSet<NavigationEntity> CurrentDbSet => DbContext.Navigation;         public override ServiceResult<NavigationEntity> Add(NavigationEntity item) public override ServiceResult<NavigationEntity> Add(NavigationEntity item)                 item.ParentId = "#";             }             item.ID = Guid.NewGuid().ToString("N");             return base.Add(item);         }         public override void Remove(NavigationEntity item)         {             Remove(m => m.ParentId == item.ID); public void Move(string id, string parentId, int position, int oldPosition)             }             Update(nav);         }     } }\ No newline at end of file

Fixed version (after fix):
 using ZKEACMS.Common.Models; using Easy; using Microsoft.EntityFrameworkCore; using ZKEACMS.Safety;  namespace ZKEACMS.Common.Service {     public class NavigationService : ServiceBase<NavigationEntity, CMSDbContext>, INavigationService     {         private readonly IHtmlSanitizer _htmlSanitizer;         public NavigationService(IApplicationContext applicationContext, CMSDbContext dbContext, IHtmlSanitizer htmlSanitizer) : base(applicationContext, dbContext)         {             _htmlSanitizer = htmlSanitizer;         }         public override DbSet<NavigationEntity> CurrentDbSet => DbContext.Navigation;         public override ServiceResult<NavigationEntity> Add(NavigationEntity item) public override ServiceResult<NavigationEntity> Add(NavigationEntity item)                 item.ParentId = "#";             }             item.ID = Guid.NewGuid().ToString("N");             Santize(item);             return base.Add(item);         }          public override ServiceResult<NavigationEntity> AddRange(params NavigationEntity[] items)         {             foreach (var item in items)             {                 Santize(item);             }             return base.AddRange(items);         }          public override ServiceResult<NavigationEntity> Update(NavigationEntity item)         {             Santize(item);             return base.Update(item);         }          public override ServiceResult<NavigationEntity> UpdateRange(params NavigationEntity[] items)         {             foreach (var item in items)             {                 Santize(item);             }             return base.UpdateRange(items);         }          public override void Remove(NavigationEntity item)         {             Remove(m => m.ParentId == item.ID); public void Move(string id, string parentId, int position, int oldPosition)             }             Update(nav);         }          private void Santize(NavigationEntity item)         {             item.Title = _htmlSanitizer.Sanitize(item.Title);             item.Html = _htmlSanitizer.Sanitize(item.Html);         }     } }\ No newline at end of file

Patch:
patch: @@ -11,13 +11,16 @@
 using ZKEACMS.Common.Models;
 using Easy;
 using Microsoft.EntityFrameworkCore;
+using ZKEACMS.Safety;
 
 namespace ZKEACMS.Common.Service
 {
     public class NavigationService : ServiceBase<NavigationEntity, CMSDbContext>, INavigationService
     {
-        public NavigationService(IApplicationContext applicationContext, CMSDbContext dbContext) : base(applicationContext, dbContext)
+        private readonly IHtmlSanitizer _htmlSanitizer;
+        public NavigationService(IApplicationContext applicationContext, CMSDbContext dbContext, IHtmlSanitizer htmlSanitizer) : base(applicationContext, dbContext)
         {
+            _htmlSanitizer = htmlSanitizer;
         }
         public override DbSet<NavigationEntity> CurrentDbSet => DbContext.Navigation;
         public override ServiceResult<NavigationEntity> Add(NavigationEntity item)
@@ -27,8 +30,34 @@ public override ServiceResult<NavigationEntity> Add(NavigationEntity item)
                 item.ParentId = "#";
             }
             item.ID = Guid.NewGuid().ToString("N");
+            Santize(item);
             return base.Add(item);
         }
+
+        public override ServiceResult<NavigationEntity> AddRange(params NavigationEntity[] items)
+        {
+            foreach (var item in items)
+            {
+                Santize(item);
+            }
+            return base.AddRange(items);
+        }
+
+        public override ServiceResult<NavigationEntity> Update(NavigationEntity item)
+        {
+            Santize(item);
+            return base.Update(item);
+        }
+
+        public override ServiceResult<NavigationEntity> UpdateRange(params NavigationEntity[] items)
+        {
+            foreach (var item in items)
+            {
+                Santize(item);
+            }
+            return base.UpdateRange(items);
+        }
+
         public override void Remove(NavigationEntity item)
         {
             Remove(m => m.ParentId == item.ID);
@@ -73,5 +102,11 @@ public void Move(string id, string parentId, int position, int oldPosition)
             }
             Update(nav);
         }
+
+        private void Santize(NavigationEntity item)
+        {
+            item.Title = _htmlSanitizer.Sanitize(item.Title);
+            item.Html = _htmlSanitizer.Sanitize(item.Html);
+        }
     }
 }
\ No newline at end of file
path: src/ZKEACMS/Common/Service/NavigationService.cs