diff --git a/ChangeLog b/ChangeLog index f73cb12dc..0a5b17094 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-04-20 Wolfgang Sourdeau + + * UI/MailPartViewers/UIxMailPartHTMLViewer.m + (-startElement:namespace:rawName:attributes:): "ignoreContent" is + no longer a BOOL but an int, and was renamed to "ignoredContent". + This enables to fix a bug where an ignored content tag could be + "unignored" by being closed more than once, triggering the passing + of further content though the sanitizer. + Also, we now rename the "classid" and "data" attributes of "object" + elements to prevent cross-site scripting. + (+initialize): "applet", "frame", "frameset" and "iframe" a now + banned tags too. + 2010-04-19 Wolfgang Sourdeau * SoObjects/Appointments/SOGoWebAppointmentFolder.m (-setReloadOnLogin:) diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.m b/UI/MailPartViewers/UIxMailPartHTMLViewer.m index 840480683..7fde4ba8b 100644 --- a/UI/MailPartViewers/UIxMailPartHTMLViewer.m +++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.m @@ -107,7 +107,7 @@ _xmlCharsetForCharset (NSString *charset) NSMutableString *result; NSMutableString *css; NSDictionary *attachmentIds; - BOOL ignoreContent; + int ignoredContent; NSString *ignoreTag; BOOL inBody; BOOL inStyle; @@ -125,11 +125,9 @@ _xmlCharsetForCharset (NSString *charset) + (void) initialize { if (!BannedTags) - { - BannedTags = [NSArray arrayWithObjects: @"script", @"link", @"base", - @"meta", @"title", nil]; - [BannedTags retain]; - } + BannedTags = [[NSArray alloc] initWithObjects: @"script", @"frameset", + @"frame", @"iframe", @"applet", @"link", + @"base", @"meta", @"title", nil]; } - (id) init @@ -190,7 +188,7 @@ _xmlCharsetForCharset (NSString *charset) result = [NSMutableString new]; css = [NSMutableString new]; - ignoreContent = NO; + ignoredContent = 0; [ignoreTag release]; ignoreTag = nil; @@ -288,7 +286,7 @@ _xmlCharsetForCharset (NSString *charset) showWhoWeAre(); lowerName = [_localName lowercaseString]; - if (inStyle || ignoreContent) + if (inStyle || ignoredContent) ; else if ([lowerName isEqualToString: @"base"]) ; @@ -302,8 +300,9 @@ _xmlCharsetForCharset (NSString *charset) { if ([BannedTags containsObject: lowerName]) { - ignoreTag = [lowerName copy]; - ignoreContent = YES; + if (!ignoredContent) + ignoreTag = [lowerName copy]; + ignoredContent++; } else { @@ -336,6 +335,13 @@ _xmlCharsetForCharset (NSString *charset) else skipAttribute = YES; } + else if (([name isEqualToString: @"data"] + || [name isEqualToString: @"classid"]) + && [lowerName isEqualToString: @"object"]) + { + value = [_attributes valueAtIndex: count]; + name = [NSString stringWithFormat: @"unsafe-%@", name]; + } else if ([name isEqualToString: @"href"] || [name isEqualToString: @"action"]) { @@ -387,13 +393,16 @@ _xmlCharsetForCharset (NSString *charset) lowerName = [_localName lowercaseString]; - if (ignoreContent) + if (ignoredContent) { if ([lowerName isEqualToString: ignoreTag]) { - ignoreContent = NO; - [ignoreTag release]; - ignoreTag = nil; + ignoredContent--; + if (!ignoredContent) + { + [ignoreTag release]; + ignoreTag = nil; + } } } else @@ -427,7 +436,7 @@ _xmlCharsetForCharset (NSString *charset) length: (int) _len { showWhoWeAre(); - if (!ignoreContent) + if (!ignoredContent) { if (inStyle) [self _appendStyle: _chars length: _len]; diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 9ca44172f..8e45ba515 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -964,17 +964,27 @@ function configureLoadImagesButton() { var imgs = content.select("IMG"); $(imgs).each(function(img) { var unsafeSrc = img.getAttribute("unsafe-src"); - if (unsafeSrc && unsafeSrc.length > 0) { + if (unsafeSrc) { hiddenImgs.push(img); } }); content.hiddenImgs = hiddenImgs; + var hiddenObjects = []; + var objects = content.select("OBJECT"); + $(objects).each(function(obj) { + if (obj.getAttribute("unsafe-data") + || obj.getAttribute("unsafe-classid")) { + hiddenObjects.push(obj); + } + }); + content.hiddenObjects = hiddenObjects; + if (typeof(loadImagesButton) == "undefined" || loadImagesButton == null ) { return; } - if (hiddenImgs.length == 0) { + if ((hiddenImgs.length + hiddenObjects.length) == 0) { loadImagesButton.setStyle({ display: 'none' }); } } @@ -1255,8 +1265,20 @@ function onMessageLoadImages(event) { log ("unsafesrc: " + unSafeSrc); img.src = img.getAttribute("unsafe-src"); }); - content.hiddenImgs = null; + $(content.hiddenObjects).each(function(obj) { + var unSafeData = obj.getAttribute("unsafe-data"); + if (unSafeData) { + obj.setAttribute("data", unSafeData); + } + var unSafeClassId = obj.getAttribute("unsafe-classid"); + if (unSafeClassId) { + obj.setAttribute("classid", unSafeClassId); + } + }); + content.hiddenObjects = null; + + var loadImagesButton = $("loadImagesButton"); loadImagesButton.setStyle({ display: 'none' });