CVE-2024-34462: Insufficient Information (NVD-CWE-noinfo)
value: Alinto SOGo through 5.10.0 allows XSS during attachment preview.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-05-04T19:15Z
Repository: https://github.com/Alinto/sogo
Language: Objective-C
Files changed: SoObjects/Mailer/SOGoMailBodyPart.m
Commit date: 2024-04-03 17:34:16 +0200
Commit message: fix(vulnerability): prevent cross-site scripting when previewing attachments

Diff: diff --git a/SoObjects/Mailer/SOGoMailBodyPart.m b/SoObjects/Mailer/SOGoMailBodyPart.m
index 7317869232..1f043d335c 100644
--- a/SoObjects/Mailer/SOGoMailBodyPart.m
+++ b/SoObjects/Mailer/SOGoMailBodyPart.m
@@ -498,53 +498,58 @@ - (id) GETAction: (WOContext *) localContext
   NSString   *etag, *mimeType, *fileName;
   id response;
 
   error = [self matchesRequestConditionInContext: localContext];
   if (error)
-    {
-      response = error; /* return 304 or 416 */
-    }
+  {
+    response = error; /* return 304 or 416 */
+  }
   else
-    {
-//   [self debugWithFormat: @"should fetch body part: %@",
+  {
+//  [self debugWithFormat: @"should fetch body part: %@",
 // 	[self bodyPartIdentifier]];
-      data = [self fetchBLOB];
-      if (data)
-	{
-//   [self debugWithFormat:@"  fetched %d bytes: %@", [data length],
-// 	[self partInfo]];
-
-	  response = [localContext response];
-	  mimeType = [self davContentType];
-	  if ([mimeType isEqualToString: @"application/x-xpinstall"])
-	    mimeType = @"application/octet-stream";
-          else if (!asAttachment)
-            mimeType = [self contentTypeForBodyPartInfo: [self partInfo]];
-
-	  [response setHeader: mimeType forKey: @"content-type"];
-	  [response setHeader: [NSString stringWithFormat:@"%d", (int)[data length]]
-		    forKey: @"content-length"];
-
-	  if (asAttachment)
-	    {
-	      fileName = [self filename];
-	      if ([fileName length])
-		[response setHeader: [NSString stringWithFormat: @"attachment; filename*=\"utf-8''%@\"",
-					       [fileName stringByEscapingURL]]
-			     forKey: @"content-disposition"];
-	    }
-
-	  etag = [self davEntityTag];
-	  if (etag)
-	    [response setHeader: etag forKey: @"etag"];
-
-	  [response setContent: data];
-	}
+    data = [self fetchBLOB];
+    if (data)
+	  {
+//    [self debugWithFormat:@"  fetched %d bytes: %@", [data length],
+// 	  [self partInfo]];
+
+	    response = [localContext response];
+	    mimeType = [self davContentType];
+
+	    if ([mimeType isEqualToString: @"application/x-xpinstall"])
+	      mimeType = @"application/octet-stream";
+      else if (!asAttachment)
+        mimeType = [self contentTypeForBodyPartInfo: [self partInfo]];
+
+      if([mimeType rangeOfString:@"xml"].location != NSNotFound || [mimeType rangeOfString:@"html"].location != NSNotFound
+         || [mimeType rangeOfString:@"css"].location != NSNotFound || [mimeType rangeOfString:@"javascript"].location != NSNotFound)
+        [response setHeader: @"text/plain" forKey: @"content-type"];
       else
-	response = [NSException exceptionWithHTTPStatus: 404 /* not found */
-				reason: @"did not find body part"];
-    }
+	      [response setHeader: mimeType forKey: @"content-type"];
+
+	    [response setHeader: [NSString stringWithFormat:@"%d", (int)[data length]] forKey: @"content-length"];
+
+      if (asAttachment)
+      {
+          fileName = [self filename];
+          if ([fileName length])
+            [response setHeader: [NSString stringWithFormat: @"attachment; filename*=\"utf-8''%@\"",
+                  [fileName stringByEscapingURL]]
+                  forKey: @"content-disposition"];
+      }
+
+      etag = [self davEntityTag];
+      if (etag)
+        [response setHeader: etag forKey: @"etag"];
+
+      [response setContent: data];
+	  }
+    else
+	    response = [NSException exceptionWithHTTPStatus: 404 /* not found */
+				  reason: @"did not find body part"];
+  }
 
   return response;
 }
 
 /* factory */

Vulnerable code:     {
      response = error; /* return 304 or 416 */
    }
    {
//   [self debugWithFormat: @"should fetch body part: %@",
      data = [self fetchBLOB];
      if (data)
	{
//   [self debugWithFormat:@"  fetched %d bytes: %@", [data length],
// 	[self partInfo]];

	  response = [localContext response];
	  mimeType = [self davContentType];
	  if ([mimeType isEqualToString: @"application/x-xpinstall"])
	    mimeType = @"application/octet-stream";
          else if (!asAttachment)
            mimeType = [self contentTypeForBodyPartInfo: [self partInfo]];

	  [response setHeader: mimeType forKey: @"content-type"];
	  [response setHeader: [NSString stringWithFormat:@"%d", (int)[data length]]
		    forKey: @"content-length"];

	  if (asAttachment)
	    {
	      fileName = [self filename];
	      if ([fileName length])
		[response setHeader: [NSString stringWithFormat: @"attachment; filename*=\"utf-8''%@\"",
					       [fileName stringByEscapingURL]]
			     forKey: @"content-disposition"];
	    }

	  etag = [self davEntityTag];
	  if (etag)
	    [response setHeader: etag forKey: @"etag"];

	  [response setContent: data];
	}
	response = [NSException exceptionWithHTTPStatus: 404 /* not found */
				reason: @"did not find body part"];
    }
Fixed code:   {
    response = error; /* return 304 or 416 */
  }
  {
//  [self debugWithFormat: @"should fetch body part: %@",
    data = [self fetchBLOB];
    if (data)
	  {
//    [self debugWithFormat:@"  fetched %d bytes: %@", [data length],
// 	  [self partInfo]];

	    response = [localContext response];
	    mimeType = [self davContentType];

	    if ([mimeType isEqualToString: @"application/x-xpinstall"])
	      mimeType = @"application/octet-stream";
      else if (!asAttachment)
        mimeType = [self contentTypeForBodyPartInfo: [self partInfo]];

      if([mimeType rangeOfString:@"xml"].location != NSNotFound || [mimeType rangeOfString:@"html"].location != NSNotFound
         || [mimeType rangeOfString:@"css"].location != NSNotFound || [mimeType rangeOfString:@"javascript"].location != NSNotFound)
        [response setHeader: @"text/plain" forKey: @"content-type"];
	      [response setHeader: mimeType forKey: @"content-type"];

	    [response setHeader: [NSString stringWithFormat:@"%d", (int)[data length]] forKey: @"content-length"];

      if (asAttachment)
      {
          fileName = [self filename];
          if ([fileName length])
            [response setHeader: [NSString stringWithFormat: @"attachment; filename*=\"utf-8''%@\"",
                  [fileName stringByEscapingURL]]
                  forKey: @"content-disposition"];
      }

      etag = [self davEntityTag];
      if (etag)
        [response setHeader: etag forKey: @"etag"];

      [response setContent: data];
	  }
    else
	    response = [NSException exceptionWithHTTPStatus: 404 /* not found */
				  reason: @"did not find body part"];
  }