From 10dc1733496fb2f393537d864d83408e357f2215 Mon Sep 17 00:00:00 2001 From: Hivert Quentin Date: Thu, 3 Sep 2026 10:51:45 +0200 Subject: [PATCH] fix(sanitization): update regex for html sanitization --- SoObjects/SOGo/NSString+Utilities.m | 57 ++++++++++++++--------------- Tests/Unit/TestNSString+Utilities.m | 14 ++++++- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index 9e5898a15..9a835676b 100644 --- a/SoObjects/SOGo/NSString+Utilities.m +++ b/SoObjects/SOGo/NSString+Utilities.m @@ -987,20 +987,28 @@ static int cssEscapingCount; // Remove javascript: regex = [NSRegularExpression regularExpressionWithPattern:@"j[\\s\\u200B \\\\0]*a[\\s\\u200B \\\\0]*v[\\s\\u200B \\\\0]*a[\\s\\u200B \\\\0]*s[\\s\\u200B \\\\0]*c[\\s\\u200B \\\\0]*r[\\s\\u200B \\\\0]*i[\\s\\u200B \\\\0]*p[\\s\\u200B \\\\0]*t[\\s\\u200B \\\\0]*:" options: NSRegularExpressionCaseInsensitive error:&error]; - newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""]; - result = [NSString stringWithString: newResult]; + // loop until stable: a single pass lets nested tokens reconstruct + // the scheme, e.g. "javajavascript:script:" -> "javascript:" + while ([regex numberOfMatchesInString:result options:0 range:NSMakeRange(0, [result length])] > 0) { + newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""]; + result = [NSString stringWithString: newResult]; + } // Remove vbscript: regex = [NSRegularExpression regularExpressionWithPattern:@"v[\\s\\u200B \\\\0]*b[\\s\\u200B \\\\0]*s[\\s\\u200B \\\\0]*c[\\s\\u200B \\\\0]*r[\\s\\u200B \\\\0]*i[\\s\\u200B \\\\0]*p[\\s\\u200B \\\\0]*t[\\s\\u200B \\\\0]*:" options: NSRegularExpressionCaseInsensitive error:&error]; - newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""]; - result = [NSString stringWithString: newResult]; + while ([regex numberOfMatchesInString:result options:0 range:NSMakeRange(0, [result length])] > 0) { + newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""]; + result = [NSString stringWithString: newResult]; + } // Remove livescript: regex = [NSRegularExpression regularExpressionWithPattern:@"l[\\s\\u200B \\\\0]*i[\\s\\u200B \\\\0]*v[\\s\\u200B \\\\0]*e[\\s\\u200B \\\\0]*s[\\s\\u200B \\\\0]*c[\\s\\u200B \\\\0]*r[\\s\\u200B \\\\0]*i[\\s\\u200B \\\\0]*p[\\s\\u200B \\\\0]*t[\\s\\u200B \\\\0]*:" options: NSRegularExpressionCaseInsensitive error:&error]; - newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""]; - result = [NSString stringWithString: newResult]; + while ([regex numberOfMatchesInString:result options:0 range:NSMakeRange(0, [result length])] > 0) { + newResult = [regex stringByReplacingMatchesInString:result options:0 range:NSMakeRange(0, [result length]) withTemplate:@""]; + result = [NSString stringWithString: newResult]; + } // Remove