CVE-2023-48104: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Alinto SOGo before 5.9.1 is vulnerable to HTML Injection.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 6.1
Published: 2024-01-16T01:15Z
Repository: https://github.com/Alinto/sogo
Language: Objective-C
Files changed: SoObjects/SOGo/NSString+Utilities.m, Tests/Unit/TestNSString+Utilities.m
Commit date: 2023-11-06 14:04:53 +0100
Commit message: fix(hmtl): prevent html injection of tag form

Diff: diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m
index 682be7e718..cf722d9238 100644
--- a/SoObjects/SOGo/NSString+Utilities.m
+++ b/SoObjects/SOGo/NSString+Utilities.m
@@ -977,10 +977,22 @@ - (NSString *) stringWithoutHTMLInjection: (BOOL)stripHTMLCode
       regex = [NSRegularExpression regularExpressionWithPattern:@"<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*i[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*f[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*a[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*m[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*e" 
                                   options: NSRegularExpressionCaseInsensitive error:&error];
       newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"<ifr***"];
       result = [NSString stringWithString: newResult];
 
+      // Remove <form
+      regex = [NSRegularExpression regularExpressionWithPattern:@"<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*f[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*o[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*m" 
+                                  options: NSRegularExpressionCaseInsensitive error:&error];
+      newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"<for*"];
+      result = [NSString stringWithString: newResult];
+
+      // Remove </form
+      regex = [NSRegularExpression regularExpressionWithPattern:@"<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*/[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*f[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*o[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*m" 
+                                  options: NSRegularExpressionCaseInsensitive error:&error];
+      newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"</for*"];
+      result = [NSString stringWithString: newResult];
+
       // Remove onload
       regex = [NSRegularExpression regularExpressionWithPattern:@"onload=" 
                                   options: NSRegularExpressionCaseInsensitive error:&error];
       newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"onl***="];
       result = [NSString stringWithString: newResult];
diff --git a/Tests/Unit/TestNSString+Utilities.m b/Tests/Unit/TestNSString+Utilities.m
index caf244c673..e0698caaf6 100644
--- a/Tests/Unit/TestNSString+Utilities.m
+++ b/Tests/Unit/TestNSString+Utilities.m
@@ -103,10 +103,11 @@ - (void) test_stringWithoutHTMLInjection
   testEquals([[NSString stringWithString:@"fb <foo@bar.com>"] stringWithoutHTMLInjection: YES], @"fb <foo@bar.com>");
   testEquals([[NSString stringWithString:@"Test\n<script>alert(\"foobar\");"] stringWithoutHTMLInjection: NO], @"Test\n<scr***>alert(\"foobar\");");
   testEquals([[NSString stringWithString:@"<img vbscript:test"] stringWithoutHTMLInjection: NO], @"<img test");
   testEquals([[NSString stringWithString:@"<img javascript:test"] stringWithoutHTMLInjection: NO], @"<img test");
   testEquals([[NSString stringWithString:@"<img livescript:test"] stringWithoutHTMLInjection: NO], @"<img test");
+  testEquals([[NSString stringWithString:@"foobar <form action=\"\">bar</form>"] stringWithoutHTMLInjection: NO], @"foobar <for* action=\"\">bar</for*>");
   testEquals([[NSString stringWithString:@"foobar <iframe src=\"\">bar</iframe>"] stringWithoutHTMLInjection: NO], @"foobar <ifr*** src=\"\">bar</iframe>");
   testEquals([[NSString stringWithString:@"foobar <img onload=foo bar"] stringWithoutHTMLInjection: NO], @"foobar <img onl***=foo bar");
   testEquals([[NSString stringWithString:@"foobar <img onmouseover=foo bar"] stringWithoutHTMLInjection: NO], @"foobar <img onmouseo***=foo bar");
 }
 

Fixed code:       // Remove <form
      regex = [NSRegularExpression regularExpressionWithPattern:@"<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*f[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*o[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*m" 
                                  options: NSRegularExpressionCaseInsensitive error:&error];
      newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"<for*"];
      result = [NSString stringWithString: newResult];

      // Remove </form
      regex = [NSRegularExpression regularExpressionWithPattern:@"<[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*/[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*f[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*o[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*r[\\s\\u200B&#x09;&#x0A;&#x0D;\\\\0]*m" 
                                  options: NSRegularExpressionCaseInsensitive error:&error];
      newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"</for*"];
      result = [NSString stringWithString: newResult];

  testEquals([[NSString stringWithString:@"foobar <form action=\"\">bar</form>"] stringWithoutHTMLInjection: NO], @"foobar <for* action=\"\">bar</for*>");