From 7532000274fc877e012b1539fdd88907d79852dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Buczek?= Date: Wed, 17 Nov 2021 18:32:55 +0100 Subject: [PATCH] Revert "Fix #4335: Deprecate ours HTTPSE in favor of the one bundled in WKWebview (#4433)" This reverts commit a3051a042fe029c5a97df0cdb42e3339b06533a8. --- BraveShared/BraveStrings.swift | 2 +- BraveShared/Shields/BraveShield.swift | 3 ++ .../Application/Delegates/AppDelegate.swift | 9 +---- .../Browser/BrowserViewController.swift | 6 +-- ...rViewController+WKNavigationDelegate.swift | 13 +++---- .../PlaylistCacheLoader.swift | 13 +++---- Client/Frontend/Browser/Tab.swift | 5 --- .../Shields/AdvancedShieldsView.swift | 2 + .../Shields/ShieldsViewController.swift | 1 + .../ContentBlocker/BlocklistName.swift | 13 +++---- .../TrackingProtectionPageStats.swift | 17 +++------ Data/models/Domain.swift | 18 ++++++--- DataTests/DomainTests.swift | 37 +++++++++++++++++++ 13 files changed, 81 insertions(+), 58 deletions(-) diff --git a/BraveShared/BraveStrings.swift b/BraveShared/BraveStrings.swift index c471ec96a6d..19b49fbbd44 100644 --- a/BraveShared/BraveStrings.swift +++ b/BraveShared/BraveStrings.swift @@ -686,7 +686,7 @@ extension Strings { public static let blockAdsAndTracking = NSLocalizedString("BlockAdsAndTracking", tableName: "BraveShared", bundle: Bundle.braveShared, value: "Block Cross-Site Trackers", comment: "") public static let blockAdsAndTrackingDescription = NSLocalizedString("BlockAdsAndTrackingDescription", tableName: "BraveShared", bundle: Bundle.braveShared, value: "Prevents ads, popups, and trackers from loading.", comment: "") public static let HTTPSEverywhere = NSLocalizedString("HTTPSEverywhere", tableName: "BraveShared", bundle: Bundle.braveShared, value: "Upgrade Connections to HTTPS", comment: "") - public static let HTTPSEverywhereDescription = NSLocalizedString("HTTPSEverywhereDescription", tableName: "BraveShared", bundle: Bundle.braveShared, value: "Opens sites using secure HTTPS instead of HTTP when possible.", comment: "") + public static let HTTPSEverywhereDescription = NSLocalizedString("HTTPSEverywhereDescription", tableName: "BraveShared", bundle: Bundle.braveShared, value: "Opens some sites using a secure HTTPS connection instead of plain HTTP.", comment: "") public static let blockPhishingAndMalware = NSLocalizedString("BlockPhishingAndMalware", tableName: "BraveShared", bundle: Bundle.braveShared, value: "Block Phishing and Malware", comment: "") public static let googleSafeBrowsing = NSLocalizedString("GoogleSafeBrowsing", tableName: "BraveShared", bundle: Bundle.braveShared, value: "Block dangerous sites", comment: "") public static let googleSafeBrowsingUsingWebKitDescription = NSLocalizedString("GoogleSafeBrowsingUsingWebKitDescription", tableName: "BraveShared", bundle: Bundle.braveShared, value: "Sends obfuscated URLs of some pages you visit to the Google Safe Browsing service, when your security is at risk.", comment: "") diff --git a/BraveShared/Shields/BraveShield.swift b/BraveShared/Shields/BraveShield.swift index 20f578cae5d..e0cc1b2934b 100644 --- a/BraveShared/Shields/BraveShield.swift +++ b/BraveShared/Shields/BraveShield.swift @@ -8,6 +8,7 @@ import Foundation public enum BraveShield { case AllOff case AdblockAndTp + case HTTPSE case SafeBrowsing case FpProtection case NoScript @@ -18,6 +19,8 @@ public enum BraveShield { return false case .AdblockAndTp: return Preferences.Shields.blockAdsAndTracking.value + case .HTTPSE: + return Preferences.Shields.httpsEverywhere.value case .SafeBrowsing: return Preferences.Shields.blockPhishingAndMalware.value case .FpProtection: diff --git a/Client/Application/Delegates/AppDelegate.swift b/Client/Application/Delegates/AppDelegate.swift index 5810a346af3..363cb2fd921 100644 --- a/Client/Application/Delegates/AppDelegate.swift +++ b/Client/Application/Delegates/AppDelegate.swift @@ -87,14 +87,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // Setup Adblock Stats and HTTPSE Stats. AdBlockStats.shared.startLoading() - - // TODO: Downgrade to 14.5 once api becomes available. - if #available(iOS 15, *) { - // do nothing, use Apple's https solution. - } else { - HttpsEverywhereStats.shared.startLoading() - } - + HttpsEverywhereStats.shared.startLoading() // Setup Application Shortcuts updateShortcutItems(application) diff --git a/Client/Frontend/Browser/BrowserViewController.swift b/Client/Frontend/Browser/BrowserViewController.swift index a5e8e497624..f7047557357 100644 --- a/Client/Frontend/Browser/BrowserViewController.swift +++ b/Client/Frontend/Browser/BrowserViewController.swift @@ -2926,19 +2926,17 @@ extension BrowserViewController: PreferencesObserver { updateApplicationShortcuts() case Preferences.General.alwaysRequestDesktopSite.key: tabManager.reset() - tabManager.reloadSelectedTab() + self.tabManager.reloadSelectedTab() case Preferences.General.enablePullToRefresh.key: tabManager.selectedTab?.updatePullToRefreshVisibility() case Preferences.Shields.blockAdsAndTracking.key, + Preferences.Shields.httpsEverywhere.key, Preferences.Shields.blockScripts.key, Preferences.Shields.blockPhishingAndMalware.key, Preferences.Shields.blockImages.key, Preferences.Shields.fingerprintingProtection.key, Preferences.Shields.useRegionAdBlock.key: tabManager.allTabs.forEach { $0.webView?.reload() } - case Preferences.Shields.httpsEverywhere.key: - tabManager.reset() - tabManager.reloadSelectedTab() case Preferences.Privacy.blockAllCookies.key, Preferences.Shields.googleSafeBrowsing.key: // All `block all cookies` toggle requires a hard reset of Webkit configuration. diff --git a/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift b/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift index 701f1743c47..211382f89b5 100644 --- a/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift +++ b/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift @@ -242,19 +242,16 @@ extension BrowserViewController: WKNavigationDelegate { pendingRequests[url.absoluteString] = navigationAction.request - // TODO: Downgrade to 14.5 once api becomes available. - if #available(iOS 15, *) { - // do nothing, use Apple's https solution. - } else { - if Preferences.Shields.httpsEverywhere.value, - url.scheme == "http", - let urlHost = url.normalizedHost() { + if let urlHost = url.normalizedHost() { + if let mainDocumentURL = navigationAction.request.mainDocumentURL, url.scheme == "http" { + let domainForShields = Domain.getOrCreate(forUrl: mainDocumentURL, persistent: !isPrivateBrowsing) HttpsEverywhereStats.shared.shouldUpgrade(url) { shouldupgrade in DispatchQueue.main.async { - if shouldupgrade { + if domainForShields.isShieldExpected(.HTTPSE, considerAllShieldsOption: true) && shouldupgrade { self.pendingHTTPUpgrades[urlHost] = navigationAction.request } } + } } } diff --git a/Client/Frontend/Browser/Playlist/Managers & Cache/PlaylistCacheLoader.swift b/Client/Frontend/Browser/Playlist/Managers & Cache/PlaylistCacheLoader.swift index 53ee01dd22f..465a339c882 100644 --- a/Client/Frontend/Browser/Playlist/Managers & Cache/PlaylistCacheLoader.swift +++ b/Client/Frontend/Browser/Playlist/Managers & Cache/PlaylistCacheLoader.swift @@ -653,16 +653,12 @@ extension PlaylistWebLoader: WKNavigationDelegate { pendingRequests[url.absoluteString] = navigationAction.request - // TODO: Downgrade to 14.5 once api becomes available. - if #available(iOS 15, *) { - // do nothing, use Apple's https solution. - } else { - if Preferences.Shields.httpsEverywhere.value, - url.scheme == "http", - let urlHost = url.normalizedHost() { + if let urlHost = url.normalizedHost() { + if let mainDocumentURL = navigationAction.request.mainDocumentURL, url.scheme == "http" { + let domainForShields = Domain.getOrCreate(forUrl: mainDocumentURL, persistent: false) HttpsEverywhereStats.shared.shouldUpgrade(url) { shouldupgrade in DispatchQueue.main.async { - if shouldupgrade { + if domainForShields.isShieldExpected(.HTTPSE, considerAllShieldsOption: true) && shouldupgrade { self.pendingHTTPUpgrades[urlHost] = navigationAction.request } } @@ -682,6 +678,7 @@ extension PlaylistWebLoader: WKNavigationDelegate { // Force adblocking on domainForShields.shield_allOff = 1 domainForShields.shield_adblockAndTp = true + domainForShields.shield_httpse = true let (on, off) = BlocklistName.blocklists(forDomain: domainForShields) let controller = webView.configuration.userContentController diff --git a/Client/Frontend/Browser/Tab.swift b/Client/Frontend/Browser/Tab.swift index d9a6e391a9b..66221b94d37 100644 --- a/Client/Frontend/Browser/Tab.swift +++ b/Client/Frontend/Browser/Tab.swift @@ -238,11 +238,6 @@ class Tab: NSObject { configuration!.ignoresViewportScaleLimits = true configuration!.mediaTypesRequiringUserActionForPlayback = Preferences.General.mediaAutoPlays.value ? [] : .all - // TODO: Downgrade to 14.5 once api becomes available. - if #available(iOS 15.0, *) { - configuration!.upgradeKnownHostsToHTTPS = Preferences.Shields.httpsEverywhere.value - } - if configuration!.urlSchemeHandler(forURLScheme: InternalURL.scheme) == nil { configuration!.setURLSchemeHandler(InternalSchemeHandler(), forURLScheme: InternalURL.scheme) } diff --git a/Client/Frontend/Shields/AdvancedShieldsView.swift b/Client/Frontend/Shields/AdvancedShieldsView.swift index 9a4c24f1c4c..47be8efeddf 100644 --- a/Client/Frontend/Shields/AdvancedShieldsView.swift +++ b/Client/Frontend/Shields/AdvancedShieldsView.swift @@ -10,6 +10,7 @@ import BraveUI class AdvancedShieldsView: UIStackView { let siteTitle = HeaderTitleView() let adsTrackersControl = ToggleView(title: Strings.blockAdsAndTracking) + let httpsUpgradesControl = ToggleView(title: Strings.HTTPSEverywhere) let blockMalwareControl = ToggleView(title: Strings.blockPhishing) let blockScriptsControl = ToggleView(title: Strings.blockScripts) let fingerprintingControl = ToggleView(title: Strings.fingerprintingProtection) @@ -26,6 +27,7 @@ class AdvancedShieldsView: UIStackView { let rows: [UIView] = [ siteTitle, adsTrackersControl, + httpsUpgradesControl, blockMalwareControl, blockScriptsControl, fingerprintingControl, diff --git a/Client/Frontend/Shields/ShieldsViewController.swift b/Client/Frontend/Shields/ShieldsViewController.swift index 77ad3fe4b8b..8c89354b03f 100644 --- a/Client/Frontend/Shields/ShieldsViewController.swift +++ b/Client/Frontend/Shields/ShieldsViewController.swift @@ -208,6 +208,7 @@ class ShieldsViewController: UIViewController, PopoverContentComponent { (.AdblockAndTp, shieldsView.advancedShieldView.adsTrackersControl, Preferences.Shields.blockAdsAndTracking), (.SafeBrowsing, shieldsView.advancedShieldView.blockMalwareControl, Preferences.Shields.blockPhishingAndMalware), (.NoScript, shieldsView.advancedShieldView.blockScriptsControl, Preferences.Shields.blockScripts), + (.HTTPSE, shieldsView.advancedShieldView.httpsUpgradesControl, Preferences.Shields.httpsEverywhere), (.FpProtection, shieldsView.advancedShieldView.fingerprintingControl, Preferences.Shields.fingerprintingProtection), ] diff --git a/Client/WebFilters/ContentBlocker/BlocklistName.swift b/Client/WebFilters/ContentBlocker/BlocklistName.swift index d4ad9dd8111..0916e207b81 100644 --- a/Client/WebFilters/ContentBlocker/BlocklistName.swift +++ b/Client/WebFilters/ContentBlocker/BlocklistName.swift @@ -19,14 +19,7 @@ class BlocklistName: CustomStringConvertible, ContentBlocker { /// List of all bundled content blockers. /// Regional lists are downloaded on fly and not included here. - static var allLists: Set { - // TODO: Downgrade to 14.5 once api becomes available. - if #available(iOS 15, *) { - return [.ad, .tracker, .image] - } else { - return [.ad, .tracker, .https, .image] - } - } + static var allLists: Set { return [.ad, .tracker, .https, .image] } let filename: String var rule: WKContentRuleList? @@ -79,6 +72,10 @@ class BlocklistName: CustomStringConvertible, ContentBlocker { // TODO #159: Setup image shield + if domain.isShieldExpected(.HTTPSE, considerAllShieldsOption: true) { + onList.insert(.https) + } + var offList = allLists.subtracting(onList) // Make sure to consider the regional list since the user may disable it globally if let regionalBlocker = regionalBlocker, !onList.contains(regionalBlocker) { diff --git a/Client/WebFilters/ContentBlocker/TrackingProtectionPageStats.swift b/Client/WebFilters/ContentBlocker/TrackingProtectionPageStats.swift index 956d0dc7307..33c80913805 100644 --- a/Client/WebFilters/ContentBlocker/TrackingProtectionPageStats.swift +++ b/Client/WebFilters/ContentBlocker/TrackingProtectionPageStats.swift @@ -91,17 +91,12 @@ class TPStatsBlocklistChecker { return } - // TODO: Downgrade to 14.5 once api becomes available. - if #available(iOS 15, *) { - // do nothing - } else { - HttpsEverywhereStats.shared.shouldUpgrade(url) { shouldUpgrade in - DispatchQueue.main.async { - if enabledLists.contains(.https) && shouldUpgrade { - completion(BlocklistName.https) - } else { - completion(nil) - } + HttpsEverywhereStats.shared.shouldUpgrade(url) { shouldUpgrade in + DispatchQueue.main.async { + if enabledLists.contains(.https) && shouldUpgrade { + completion(BlocklistName.https) + } else { + completion(nil) } } } diff --git a/Data/models/Domain.swift b/Data/models/Domain.swift index 820153df805..a9eb1b1d1f0 100644 --- a/Data/models/Domain.swift +++ b/Data/models/Domain.swift @@ -18,10 +18,7 @@ public final class Domain: NSManagedObject, CRUD { @NSManaged public var shield_allOff: NSNumber? @NSManaged public var shield_adblockAndTp: NSNumber? - - @available(*, deprecated, message: "Per domain HTTPSE shield is currently unused.") @NSManaged public var shield_httpse: NSNumber? - @NSManaged public var shield_noScript: NSNumber? @NSManaged public var shield_fpProtection: NSNumber? @NSManaged public var shield_safeBrowsing: NSNumber? @@ -84,6 +81,8 @@ public final class Domain: NSManagedObject, CRUD { return self.shield_allOff?.boolValue ?? false case .AdblockAndTp: return self.shield_adblockAndTp?.boolValue ?? Preferences.Shields.blockAdsAndTracking.value + case .HTTPSE: + return self.shield_httpse?.boolValue ?? Preferences.Shields.httpsEverywhere.value case .SafeBrowsing: return self.shield_safeBrowsing?.boolValue ?? Preferences.Shields.blockPhishingAndMalware.value case .FpProtection: @@ -91,10 +90,10 @@ public final class Domain: NSManagedObject, CRUD { case .NoScript: return self.shield_noScript?.boolValue ?? Preferences.Shields.blockScripts.value } - }() + } let isAllShieldsOff = Bool(truncating: shield_allOff ?? NSNumber(value: 0)) - let isSpecificShieldOn = isShieldOn + let isSpecificShieldOn = isShieldOn() return considerAllShieldsOption ? !isAllShieldsOff && isSpecificShieldOn : isSpecificShieldOn } @@ -121,6 +120,7 @@ public final class Domain: NSManagedObject, CRUD { httpsDomain.shield_noScript = domain.shield_noScript httpsDomain.shield_fpProtection = domain.shield_fpProtection httpsDomain.shield_safeBrowsing = domain.shield_safeBrowsing + httpsDomain.shield_httpse = domain.shield_httpse // Could call `domain.delete()` here (or add to batch to delete) } } @@ -229,6 +229,12 @@ extension Domain { switch shield { case .AllOff: shield_allOff = setting case .AdblockAndTp: shield_adblockAndTp = setting + case .HTTPSE: + shield_httpse = setting + + // HTTPSE must be scheme indepedent or user may get stuck not being able to access the http version + // of a website (turning off httpse for an upgraded-https domain does not allow access to http version) + self.domainForInverseHttpScheme(context: context)?.shield_httpse = setting case .SafeBrowsing: shield_safeBrowsing = setting case .FpProtection: shield_fpProtection = setting case .NoScript: shield_noScript = setting @@ -242,6 +248,8 @@ extension Domain { return self.shield_allOff?.boolValue case .AdblockAndTp: return self.shield_adblockAndTp?.boolValue + case .HTTPSE: + return self.shield_httpse?.boolValue case .SafeBrowsing: return self.shield_safeBrowsing?.boolValue case .FpProtection: diff --git a/DataTests/DomainTests.swift b/DataTests/DomainTests.swift index 16466a474ca..db13a0fea12 100644 --- a/DataTests/DomainTests.swift +++ b/DataTests/DomainTests.swift @@ -50,6 +50,7 @@ class DomainTests: CoreDataTestCase { let domain = Domain.getOrCreate(forUrl: url, persistent: true) XCTAssertTrue(domain.isShieldExpected(BraveShield.AdblockAndTp, considerAllShieldsOption: true)) + XCTAssertTrue(domain.isShieldExpected(BraveShield.HTTPSE, considerAllShieldsOption: true)) XCTAssertTrue(domain.isShieldExpected(BraveShield.SafeBrowsing, considerAllShieldsOption: true)) XCTAssertFalse(domain.isShieldExpected(BraveShield.AllOff, considerAllShieldsOption: true)) XCTAssertFalse(domain.isShieldExpected(BraveShield.NoScript, considerAllShieldsOption: true)) @@ -68,6 +69,7 @@ class DomainTests: CoreDataTestCase { } XCTAssertFalse(domain.isShieldExpected(BraveShield.AdblockAndTp, considerAllShieldsOption: true)) + XCTAssertFalse(domain.isShieldExpected(BraveShield.HTTPSE, considerAllShieldsOption: true)) XCTAssertTrue(domain.isShieldExpected(BraveShield.SafeBrowsing, considerAllShieldsOption: false)) XCTAssertFalse(domain.isShieldExpected(BraveShield.AllOff, considerAllShieldsOption: true)) XCTAssertFalse(domain.isShieldExpected(BraveShield.NoScript, considerAllShieldsOption: true)) @@ -78,6 +80,7 @@ class DomainTests: CoreDataTestCase { } XCTAssertTrue(domain.isShieldExpected(BraveShield.AdblockAndTp, considerAllShieldsOption: true)) + XCTAssertTrue(domain.isShieldExpected(BraveShield.HTTPSE, considerAllShieldsOption: true)) XCTAssertTrue(domain.isShieldExpected(BraveShield.SafeBrowsing, considerAllShieldsOption: true)) XCTAssertFalse(domain.isShieldExpected(BraveShield.AllOff, considerAllShieldsOption: true)) XCTAssertFalse(domain.isShieldExpected(BraveShield.NoScript, considerAllShieldsOption: true)) @@ -114,4 +117,38 @@ class DomainTests: CoreDataTestCase { XCTAssertTrue(domain.isShieldExpected(BraveShield.SafeBrowsing, considerAllShieldsOption: true)) XCTAssertTrue(domain.isShieldExpected(BraveShield.AdblockAndTp, considerAllShieldsOption: true)) } + + /// Testing HTTPSE + /// if setting an HTTP scheme, that HTTPS is also set + func testHTTPSEforHTTPsetter() { + backgroundSaveAndWaitForExpectation { + Domain.setBraveShield(forUrl: url, shield: .HTTPSE, isOn: true, isPrivateBrowsing: false) + } + + // Should be one for HTTP and one for HTTPS schemes + XCTAssertEqual(try! DataController.viewContext.count(for: fetchRequest), 2) + + let domainRefetch1 = Domain.getOrCreate(forUrl: url, persistent: true) + XCTAssertEqual(domainRefetch1.isShieldExpected(.HTTPSE, considerAllShieldsOption: true), true) + + let domainRefetch2 = Domain.getOrCreate(forUrl: urlHTTPS, persistent: true) + XCTAssertEqual(domainRefetch2.isShieldExpected(.HTTPSE, considerAllShieldsOption: true), true) + } + + /// Testing HTTPSE + /// if setting an HTTPS scheme, that HTTP is also set + func testHTTPSEforHTTPSsetter() { + backgroundSaveAndWaitForExpectation { + Domain.setBraveShield(forUrl: url2HTTPS, shield: .HTTPSE, isOn: true, isPrivateBrowsing: false) + } + + // Should be one for HTTP and one for HTTPS schemes + XCTAssertEqual(try! DataController.viewContext.count(for: fetchRequest), 2) + + let domainRefetch1 = Domain.getOrCreate(forUrl: url2, persistent: true) + XCTAssertEqual(domainRefetch1.isShieldExpected(.HTTPSE, considerAllShieldsOption: true), true) + + let domainRefetch2 = Domain.getOrCreate(forUrl: url2HTTPS, persistent: true) + XCTAssertEqual(domainRefetch2.isShieldExpected(.HTTPSE, considerAllShieldsOption: true), true) + } }