From f61b5ad3a91bb44eb4f3df4dde595da624942baa Mon Sep 17 00:00:00 2001 From: Kuba Adamczyk Date: Mon, 26 Jan 2026 12:26:00 +0100 Subject: [PATCH 1/2] implement MIME type blacklist --- apple/RNCWebViewImpl.m | 44 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/apple/RNCWebViewImpl.m b/apple/RNCWebViewImpl.m index 5fbe05b7b..d497849cb 100644 --- a/apple/RNCWebViewImpl.m +++ b/apple/RNCWebViewImpl.m @@ -1451,6 +1451,42 @@ - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView } } +/** + * Determines if a MIME type should be blocked from rendering. + */ +- (BOOL)shouldBlockMIMETypeFromRendering:(NSString *)mimeType { + if (mimeType == nil) { + return NO; + } + + NSString *normalizedType = [[mimeType componentsSeparatedByString:@";"].firstObject + stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + normalizedType = [normalizedType lowercaseString]; + + static NSSet *blockedTypes = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + blockedTypes = [NSSet setWithObjects: + @"application/octet-stream", + @"application/x-msdownload", + @"application/x-executable", + @"application/x-dosexec", + @"application/zip", + @"application/x-zip-compressed", + @"application/x-rar-compressed", + @"application/x-7z-compressed", + @"application/x-tar", + @"application/gzip", + @"application/x-gzip", + @"application/x-bzip2", + @"application/x-msi", + nil + ]; + }); + + return [blockedTypes containsObject:normalizedType]; +} + /** * Decides whether to allow or cancel a navigation after its response is known. * @see https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview?language=objc @@ -1479,16 +1515,18 @@ - (void) webView:(WKWebView *)webView disposition = [response valueForHTTPHeaderField:@"Content-Disposition"]; } BOOL isAttachment = disposition != nil && [disposition hasPrefix:@"attachment"]; - if (isAttachment || !navigationResponse.canShowMIMEType) { - if (_onFileDownload) { - policy = WKNavigationResponsePolicyCancel; + NSString *contentType = [response valueForHTTPHeaderField:@"Content-Type"]; + BOOL isUnsafeMIMEType = [self shouldBlockMIMETypeFromRendering:contentType]; + if (isAttachment || !navigationResponse.canShowMIMEType || isUnsafeMIMEType) { + if (_onFileDownload) { NSMutableDictionary *downloadEvent = [self baseEvent]; [downloadEvent addEntriesFromDictionary: @{ @"downloadUrl": (response.URL).absoluteString, }]; _onFileDownload(downloadEvent); } + policy = WKNavigationResponsePolicyCancel; } } From dbe76c72b2149821398429caa78e3863faf24f2a Mon Sep 17 00:00:00 2001 From: Kuba Adamczyk Date: Mon, 26 Jan 2026 12:27:44 +0100 Subject: [PATCH 2/2] changeset --- .changeset/calm-taxis-poke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/calm-taxis-poke.md diff --git a/.changeset/calm-taxis-poke.md b/.changeset/calm-taxis-poke.md new file mode 100644 index 000000000..7c8166621 --- /dev/null +++ b/.changeset/calm-taxis-poke.md @@ -0,0 +1,5 @@ +--- +'@phantom/react-native-webview': patch +--- + +Implement MIME type blacklist.