From 8b7bdeb151c2fab7460a722403a52f8e8078b7b6 Mon Sep 17 00:00:00 2001 From: Brandon Date: Wed, 15 Apr 2020 17:09:03 -0400 Subject: [PATCH] Fixed to only exclude and include specific data-uri's. --- Client.xcodeproj/project.pbxproj | 4 ++ ...rViewController+WKNavigationDelegate.swift | 49 ++++++++++++++++++- Client/Frontend/Browser/DataURIParser.swift | 36 ++++++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 Client/Frontend/Browser/DataURIParser.swift diff --git a/Client.xcodeproj/project.pbxproj b/Client.xcodeproj/project.pbxproj index f3656adb5d3..2598e83c8ff 100644 --- a/Client.xcodeproj/project.pbxproj +++ b/Client.xcodeproj/project.pbxproj @@ -670,6 +670,7 @@ 5E0FCD212342526700AC831E /* FullscreenHelper.js in Resources */ = {isa = PBXBuildFile; fileRef = 5EB57D0122FDC0CB00A07325 /* FullscreenHelper.js */; }; 5E0FCD23234253DC00AC831E /* CertificatePinning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E0FCD22234253DC00AC831E /* CertificatePinning.swift */; }; 5E0FCD252342544C00AC831E /* URLSession+Requests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E0FCD242342544C00AC831E /* URLSession+Requests.swift */; }; + 5E2137EF24479D28005FC9DE /* DataURIParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E2137EE24479D28005FC9DE /* DataURIParser.swift */; }; 5E3477E922D7771700B0D5F8 /* ResourceDownloader.js in Resources */ = {isa = PBXBuildFile; fileRef = 5E3477E822D7771700B0D5F8 /* ResourceDownloader.js */; }; 5E34781022D7A1D200B0D5F8 /* ResourceDownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E34780F22D7A1D200B0D5F8 /* ResourceDownloadManager.swift */; }; 5E46C371234FACC600ACA8C1 /* root.cer in Resources */ = {isa = PBXBuildFile; fileRef = 5E46C36D234FACC600ACA8C1 /* root.cer */; }; @@ -2140,6 +2141,7 @@ 5E1D8C6A232BF95200BDE662 /* OnboardingRewardsAgreementViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingRewardsAgreementViewController.swift; sourceTree = ""; }; 5E1D8C6C232BF9C200BDE662 /* OnboardingRewardsAgreementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingRewardsAgreementView.swift; sourceTree = ""; }; 5E1D8C6E232C0BDB00BDE662 /* onboarding-rewards.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "onboarding-rewards.json"; sourceTree = ""; }; + 5E2137EE24479D28005FC9DE /* DataURIParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataURIParser.swift; sourceTree = ""; }; 5E3477E822D7771700B0D5F8 /* ResourceDownloader.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = ResourceDownloader.js; sourceTree = ""; }; 5E34780F22D7A1D200B0D5F8 /* ResourceDownloadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResourceDownloadManager.swift; sourceTree = ""; }; 5E46C36D234FACC600ACA8C1 /* root.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = root.cer; sourceTree = ""; }; @@ -4458,6 +4460,7 @@ 5E4845C122DE3DF800372022 /* WindowRenderHelperScript.swift */, 0A19365323508756002E2B81 /* LinkPreviewViewController.swift */, 0A66550923E9D9750047EF2A /* UserAgent.swift */, + 5E2137EE24479D28005FC9DE /* DataURIParser.swift */, ); indentWidth = 4; path = Browser; @@ -6202,6 +6205,7 @@ 4422D56321BFFB7F00BF1855 /* compile.cc in Sources */, D3C3696E1CC6B78800348A61 /* LocalRequestHelper.swift in Sources */, 27C461DE211B76500088A441 /* ShieldsView.swift in Sources */, + 5E2137EF24479D28005FC9DE /* DataURIParser.swift in Sources */, E4B423DD1ABA0318007E66C8 /* ReaderModeHandlers.swift in Sources */, 4422D4DA21BFFB7600BF1855 /* iterator.cc in Sources */, 4422D4AF21BFFB7600BF1855 /* status.cc in Sources */, diff --git a/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift b/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift index 7c26c5d59b7..2ee0c00c57f 100644 --- a/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift +++ b/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift @@ -261,9 +261,54 @@ extension BrowserViewController: WKNavigationDelegate { // Prevents synthetically activated links such as: CVE-2017-7089 //Follow desktop + /* + User explicitly entering/pasting “data:…” into the address bar + Opening all plain text data files + Opening “data:image/*” in top-level window, unless it’s “data:image/svg+xml” + Opening “data:application/pdf” and “data:application/json” + Downloading a data: URL, e.g. ‘save-link-as’ of “data:…” + + https://blog.mozilla.org/security/2017/11/27/blocking-top-level-navigations-data-urls-firefox-59/ + */ + if url.scheme == "data" { - decisionHandler(.cancel) - return + do { + //A click is synthetic if its value is 0 (aka WKSyntheticClickTypeNoTap). + //Or if its navigationType is "other". + if let clickType = navigationAction.value(forKey: "syntheticClickType") as? Int, clickType == 0 || navigationAction.navigationType == .other { + /*case WebKit::WebMouseEvent::OneFingerTap: + return WKSyntheticClickTypeOneFingerTap; + case WebKit::WebMouseEvent::TwoFingerTap: + return WKSyntheticClickTypeTwoFingerTap; + }*/ + return decisionHandler(.cancel) + } + + let allowedMimeTypes = ["image", "text/json", + "text/plain", "text/css", + "audio", "video", + "application", + "application/pdf", "application/json"] + + let blockedMimeTypes = ["image/svg+xml", "text/html", + "text/xhtml", "text/xml", + "application/xhtml", "application/html", + "application/xml" + ] + + let URIInfo = try DataURIParser(uri: url.absoluteString) + if blockedMimeTypes.contains(URIInfo.mediaType) { + return decisionHandler(.cancel) + } + + if allowedMimeTypes.contains(URIInfo.mediaType) { + return decisionHandler(.allow) + } + + return decisionHandler(.cancel) + } catch { + return + } } decisionHandler(.allow) diff --git a/Client/Frontend/Browser/DataURIParser.swift b/Client/Frontend/Browser/DataURIParser.swift new file mode 100644 index 00000000000..5deb10de988 --- /dev/null +++ b/Client/Frontend/Browser/DataURIParser.swift @@ -0,0 +1,36 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import Foundation + +class DataURIParser { + let mediaType: String + let headers: [String] + let data: Data + + init(uri: String) throws { + if uri == "data:," { + mediaType = "text/plain" + headers = ["charset=US-ASCII"] + data = Data() + return + } + + if !uri.lowercased().hasPrefix("data:") { + throw "Invalid Data-URI" + } + + guard let infoSegment = uri.firstIndex(of: ",") else { + throw "Invalid Data-URI" + } + + let startSegment = uri.index(uri.startIndex, offsetBy: "data:".count) + self.headers = uri[startSegment..