Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Fixed to only exclude and include specific data-uri's.
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon-T committed Apr 15, 2020
1 parent de588d1 commit 8b7bdeb
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Client.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -2140,6 +2141,7 @@
5E1D8C6A232BF95200BDE662 /* OnboardingRewardsAgreementViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingRewardsAgreementViewController.swift; sourceTree = "<group>"; };
5E1D8C6C232BF9C200BDE662 /* OnboardingRewardsAgreementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingRewardsAgreementView.swift; sourceTree = "<group>"; };
5E1D8C6E232C0BDB00BDE662 /* onboarding-rewards.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "onboarding-rewards.json"; sourceTree = "<group>"; };
5E2137EE24479D28005FC9DE /* DataURIParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataURIParser.swift; sourceTree = "<group>"; };
5E3477E822D7771700B0D5F8 /* ResourceDownloader.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = ResourceDownloader.js; sourceTree = "<group>"; };
5E34780F22D7A1D200B0D5F8 /* ResourceDownloadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResourceDownloadManager.swift; sourceTree = "<group>"; };
5E46C36D234FACC600ACA8C1 /* root.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = root.cer; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4458,6 +4460,7 @@
5E4845C122DE3DF800372022 /* WindowRenderHelperScript.swift */,
0A19365323508756002E2B81 /* LinkPreviewViewController.swift */,
0A66550923E9D9750047EF2A /* UserAgent.swift */,
5E2137EE24479D28005FC9DE /* DataURIParser.swift */,
);
indentWidth = 4;
path = Browser;
Expand Down Expand Up @@ -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 */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
36 changes: 36 additions & 0 deletions Client/Frontend/Browser/DataURIParser.swift
Original file line number Diff line number Diff line change
@@ -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..<infoSegment].split(separator: ";").map({ String($0) })
mediaType = headers.first ?? "text/plain"

let dataSegment = uri.index(infoSegment, offsetBy: 1)
//data = try! Data(contentsOf: URL(string: uri)!)
data = Data(base64Encoded: String(uri[dataSegment..<uri.endIndex])) ?? Data()
}
}

0 comments on commit 8b7bdeb

Please sign in to comment.