mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-08-28 17:57:38 +00:00
Merge pull request #395 from kah-ja/fix/imip-card-template-injection
fix(mail): stop interpreting mail data in compiled part viewers
This commit is contained in:
@@ -942,12 +942,13 @@ static int cssEscapingCount;
|
||||
NSScanner *theScanner;
|
||||
NSError *error;
|
||||
NSUInteger numberOfMatches;
|
||||
NSRegularExpression *regex;
|
||||
NSRegularExpression *regex, *importRegex;
|
||||
|
||||
text = nil;
|
||||
error = nil;
|
||||
result = [NSString stringWithString: self];
|
||||
regex = nil;
|
||||
importRegex = nil;
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
@@ -1056,9 +1057,9 @@ static int cssEscapingCount;
|
||||
result = [NSString stringWithString: newResult];
|
||||
|
||||
// Remove @import css (in style tags)
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:@"(<[\\s\\u200B	

\\\\0]*s[\\s\\u200B	

\\\\0]*t[\\s\\u200B	

\\\\0]*y[\\s\\u200B	

\\\\0]*l[\\s\\u200B	

\\\\0]*e.*)([\\s\\u200B	

\\\\0]*@[\\s\\u200B	

\\\\0]*i[\\s\\u200B	

\\\\0]*m[\\s\\u200B	

\\\\0]*p[\\s\\u200B	

\\\\0]*o[\\s\\u200B	

\\\\0]*r[\\s\\u200B	

\\\\0]*t)(.*<[\\s\\u200B	

\\\\0]*\\/[\\s\\u200B	

\\\\0]*s[\\s\\u200B	

\\\\0]*t[\\s\\u200B	

\\\\0]*y[\\s\\u200B	

\\\\0]*l[\\s\\u200B	

\\\\0]*e[\\s\\u200B	

\\\\0]*>)"
|
||||
importRegex = [NSRegularExpression regularExpressionWithPattern:@"(<[\\s\\u200B	

\\\\0]*s[\\s\\u200B	

\\\\0]*t[\\s\\u200B	

\\\\0]*y[\\s\\u200B	

\\\\0]*l[\\s\\u200B	

\\\\0]*e.*)([\\s\\u200B	

\\\\0]*@[\\s\\u200B	

\\\\0]*i[\\s\\u200B	

\\\\0]*m[\\s\\u200B	

\\\\0]*p[\\s\\u200B	

\\\\0]*o[\\s\\u200B	

\\\\0]*r[\\s\\u200B	

\\\\0]*t)(.*<[\\s\\u200B	

\\\\0]*\\/[\\s\\u200B	

\\\\0]*s[\\s\\u200B	

\\\\0]*t[\\s\\u200B	

\\\\0]*y[\\s\\u200B	

\\\\0]*l[\\s\\u200B	

\\\\0]*e[\\s\\u200B	

\\\\0]*>)"
|
||||
options: NSRegularExpressionCaseInsensitive error:&error];
|
||||
newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"onrep***="];
|
||||
newResult = [importRegex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@"$1@im****$3"];
|
||||
result = [NSString stringWithString: newResult];
|
||||
|
||||
|
||||
@@ -1075,8 +1076,8 @@ static int cssEscapingCount;
|
||||
}
|
||||
|
||||
newResult = result;
|
||||
while([regex numberOfMatchesInString:newResult options:0 range:NSMakeRange(0, [newResult length])] > 0) {
|
||||
newResult = [regex stringByReplacingMatchesInString:newResult options:0 range:NSMakeRange(0, [newResult length]) withTemplate:@"$1@im****$3"];
|
||||
while([importRegex numberOfMatchesInString:newResult options:0 range:NSMakeRange(0, [newResult length])] > 0) {
|
||||
newResult = [importRegex stringByReplacingMatchesInString:newResult options:0 range:NSMakeRange(0, [newResult length]) withTemplate:@"$1@im****$3"];
|
||||
}
|
||||
result = [NSString stringWithString: newResult];
|
||||
}
|
||||
|
||||
@@ -110,6 +110,8 @@
|
||||
testEquals([[NSString stringWithString:@"foobar <img onload=foo bar"] stringWithoutHTMLInjection: NO stripAngular: NO], @"foobar <img onl***=foo bar");
|
||||
testEquals([[NSString stringWithString:@"foobar <img onmouseover=foo bar"] stringWithoutHTMLInjection: NO stripAngular: NO], @"foobar <img onmouseo***=foo bar");
|
||||
testEquals([[NSString stringWithString:@"<!DOCTYPE html><html><head><style>@import url(https://foo.bar/malicious.css);.foo{background-color: red; @import url(https://bar.foo/malicious2.css);</style></head><body><table><tr><td>A</td><td>B</td><td>C</td></tr></table></body></html>"] stringWithoutHTMLInjection: NO stripAngular: NO], @"<!DOCTYPE html><html><head><style>@im**** url(https://foo.bar/malicious.css);.foo{background-color: red; @im**** url(https://bar.foo/malicious2.css);</style></head><body><table><tr><td>A</td><td>B</td><td>C</td></tr></table></body></html>");
|
||||
// the @import cleanup must still run when angular interpolation is stripped as well
|
||||
testEquals([[NSString stringWithString:@"<style>@import url(https://foo.bar/malicious.css);</style>"] stringWithoutHTMLInjection: NO stripAngular: YES], @"<style>@im**** url(https://foo.bar/malicious.css);</style>");
|
||||
}
|
||||
|
||||
- (void) test_stringCleanInvalidHTMLTags
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
- (BOOL) isEndDateOnSameDay;
|
||||
- (BOOL) hasLocation;
|
||||
- (NSString *)location;
|
||||
- (NSString *) organizerHref;
|
||||
- (NSString *) userComment;
|
||||
- (NSString *) eventDescription;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
|
||||
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
||||
|
||||
@@ -417,6 +418,18 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *) organizerHref
|
||||
{
|
||||
NSString *address;
|
||||
|
||||
address = [[[self inEvent] organizer] rfc822Email];
|
||||
if (![address length])
|
||||
return nil;
|
||||
|
||||
return [[NSString stringWithFormat: @"mailto:%@", address]
|
||||
stringByEscapingHTMLAttributeValue];
|
||||
}
|
||||
|
||||
- (NSString *) organizerDisplayName
|
||||
{
|
||||
iCalPerson *organizer;
|
||||
@@ -612,4 +625,14 @@
|
||||
return [[self inEvent] location];
|
||||
}
|
||||
|
||||
- (NSString *) userComment
|
||||
{
|
||||
return [[[self inEvent] userComment] stringByEscapingHTMLString];
|
||||
}
|
||||
|
||||
- (NSString *) eventDescription
|
||||
{
|
||||
return [[[self authorativeEvent] comment] stringByEscapingHTMLString];
|
||||
}
|
||||
|
||||
@end /* UIxMailPartICalViewer */
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
- (NSString *)preferredPathExtension;
|
||||
- (NSString *)filename;
|
||||
- (NSString *)filenameForDisplay;
|
||||
- (NSString *)filenameForTitle;
|
||||
- (NSFormatter *)sizeFormatter;
|
||||
|
||||
/* caches */
|
||||
|
||||
@@ -340,6 +340,14 @@
|
||||
: (id)@"untitled";
|
||||
}
|
||||
|
||||
- (NSString *) filenameForTitle
|
||||
{
|
||||
/* the generic attribute writer escapes & but not the quote, so a quote in the
|
||||
filename would end the title attribute and start a new one */
|
||||
return [[self filenameForDisplay] stringByReplacingOccurrencesOfString: @"\""
|
||||
withString: @""];
|
||||
}
|
||||
|
||||
- (NSFormatter *) sizeFormatter
|
||||
{
|
||||
return [UIxMailSizeFormatter sharedMailSizeFormatter];
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-whiteframe class="md-whiteframe-z1" layout="row" layout-align="space-between center">
|
||||
<pre><var:string value="flatContentAsString" /></pre>
|
||||
<pre ng-non-bindable=""><var:string value="flatContentAsString" /></pre>
|
||||
</md-whiteframe>
|
||||
</div>
|
||||
</var:if> <!-- if condition="couldParseCalendar" const:negate="1" -->
|
||||
@@ -137,7 +137,7 @@
|
||||
|
||||
<p>
|
||||
<var:string label:value="Organizer" />
|
||||
<a var:href="inEvent.organizer.email"
|
||||
<a ng-non-bindable="" var:href="organizerHref"
|
||||
><var:string value="organizerDisplayName" /></a>
|
||||
<var:string label:value="request_info" />
|
||||
</p>
|
||||
@@ -147,7 +147,7 @@
|
||||
<var:if condition="isLoggedInUserAnAttendee" const:negate="YES">
|
||||
<p>
|
||||
<var:string label:value="Organizer" />
|
||||
<a var:href="inEvent.organizer.email">
|
||||
<a ng-non-bindable="" var:href="organizerHref">
|
||||
<var:string value="organizerDisplayName" />
|
||||
</a>
|
||||
<var:string label:value="request_info_no_attendee" />
|
||||
@@ -233,14 +233,14 @@
|
||||
</var:if>
|
||||
|
||||
<!-- the user comment is used in replies -->
|
||||
<var:if condition="inEvent.userComment.isNotEmpty">
|
||||
<var:if condition="userComment.isNotEmpty">
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="Comment"/>
|
||||
</label>
|
||||
<div>
|
||||
<div ng-non-bindable="">
|
||||
<md-content>
|
||||
<var:string value="inEvent.userComment.stringByDetectingURLs" const:insertBR="1" const:escapeHTML="NO"/>
|
||||
<var:string value="userComment.stringByDetectingURLs" const:insertBR="1" const:escapeHTML="NO"/>
|
||||
</md-content>
|
||||
</div>
|
||||
</div>
|
||||
@@ -251,7 +251,7 @@
|
||||
<var:if condition="hasOrganizer" const:value="true">
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="Organizer"/></label>
|
||||
<div>
|
||||
<div ng-non-bindable="">
|
||||
<var:string value="organizerDisplayName"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -268,7 +268,7 @@
|
||||
<var:if condition="hasLocation">
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="Location"/></label>
|
||||
<div>
|
||||
<div ng-non-bindable="">
|
||||
<var:string value="location"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -294,14 +294,14 @@
|
||||
</div>
|
||||
</md-list>
|
||||
|
||||
<var:if condition="authorativeEvent.comment.isNotEmpty">
|
||||
<var:if condition="eventDescription.isNotEmpty">
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="Description"/>
|
||||
</label>
|
||||
<div ng-non-bindable="">
|
||||
<md-content>
|
||||
<var:string value="authorativeEvent.comment.stringByDetectingURLs" const:insertBR="1" const:escapeHTML="NO"/>
|
||||
<var:string value="eventDescription.stringByDetectingURLs" const:insertBR="1" const:escapeHTML="NO"/>
|
||||
</md-content>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<img var:src="pathToAttachment"
|
||||
var:title="filenameForDisplay"><!-- image --></img>
|
||||
<md-card-content>
|
||||
<p class="md-caption" var:title="filenameForDisplay">
|
||||
<p class="md-caption" var:title="filenameForTitle">
|
||||
<var:string value="filenameForDisplay" />
|
||||
</p>
|
||||
</md-card-content>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
xmlns:label="OGo:label">
|
||||
<md-card>
|
||||
<md-card-content>
|
||||
<p class="md-caption sg-attachment-name" var:title="filenameForDisplay">
|
||||
<p class="md-caption sg-attachment-name" var:title="filenameForTitle">
|
||||
<var:if condition="preferredPathExtension.length"><span class="sg-label-outline"><var:string value="preferredPathExtension"/></span></var:if>
|
||||
<var:string value="filenameForDisplay"/>
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user