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

Fix #2424: Disabling Synthetic clicks on WebPages #2419

Open
wants to merge 5 commits into
base: development
Choose a base branch
from

Conversation

Brandon-T
Copy link
Collaborator

@Brandon-T Brandon-T commented Mar 22, 2020

Security Review

https://github.com/brave/security/issues/104

Test Plan

  1. Go to reddit or any site with a login
  2. Tap the URL bar and type https://loving-newton-6b489c.netlify.com/
  3. Hit Enter and make sure you do NOT get a pop!
  4. If you see a link on the page and you tap on it, it should ask you are you sure you want to open it.
  5. If you manually type any data URIs into the URL bar, it should give a prompt to ask whether you want to open it or not.

Summary of Changes

  • Detect synthetic click types and automatically block them.
  • If this cannot be done, ask the user if they wish to proceed.
  • If the url can't be opened, then it will just show an error.

Other Browser:

  • Safari: Attempts to open the URL but gives an error Safari cannot open this URL then proceeds to show the 2 popups.
  • Chrome: Automatically begins downloading the document
  • Firefox: Same behaviour as current Brave-iOS.. It shows the two popups but does NOT show the document cookies or any other sensitive information because parent-tab:// is not a valid URL. If it were, we'd be in trouble. In both cases (brave and firefox), it's a minor UXSS attack.

This pull request fixes #2422 && #2424

Submitter Checklist:

  • Unit Tests are updated to cover new or changed functionality
  • User-facing strings use NSLocalizableString()

Test Plan:

Screenshots:

Reviewer Checklist:

  • Issues include necessary QA labels:
    • QA/(Yes|No)
    • release-notes/(include|exclude)
    • bug / enhancement
  • Necessary security reviews have taken place.
  • Adequate unit test coverage exists to prevent regressions.
  • Adequate test plan exists for QA to validate (if applicable).
  • Issue is assigned to a milestone (should happen at merge time).

Copy link
Collaborator

@iccub iccub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add:

  • regular ticket in brave-ios
  • sec-review ticket
  • test plan for QA

Code looks good so approving it

@iccub iccub changed the title Fix for Synthetic Clicks and parsing of data scheme URLs - CVE-2017-7089 Fix #2422: CVE-2017-7089 Mar 24, 2020
@Brandon-T Brandon-T changed the title Fix #2422: CVE-2017-7089 Fix #2422: Disabling Synthetic clicks on WebPages Mar 24, 2020

//Fallback.. Asks the user whether or not the url should be opened.. but only for `data`
if navigationAction.navigationType == .linkActivated && url.scheme == "data" {
handleExternalURL(url) { didOpenURL in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data is not an external URL. This code essentially disables data urls (which is tracked as a different issue). I tried this code snippet using this URL: https://jumde.github.io/test/data-url.hml and clicking hello, the data URL cannot be opened.

@Brandon-T Brandon-T changed the title Fix #2422: Disabling Synthetic clicks on WebPages Fix #2422 & #2424: Disabling Synthetic clicks on WebPages Mar 24, 2020
@iccub iccub changed the title Fix #2422 & #2424: Disabling Synthetic clicks on WebPages Fix #2424: Disabling Synthetic clicks on WebPages Mar 25, 2020
@iccub iccub linked an issue Mar 25, 2020 that may be closed by this pull request

// Prevents synthetically activated links such as: CVE-2017-7089
//Follow desktop
if url.scheme == "data" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this also block window.open('data:...')?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@diracdeltas I have implemented: https://blog.mozilla.org/security/2017/11/27/blocking-top-level-navigations-data-urls-firefox-59/

It does indeed block window.open. I tested against the latest Firefox-Quantum to make sure our behaviour is the same.

@garvankeeley
Copy link

Curious what y'all think of an approach like this mozilla-mobile/firefox-ios#6341
On Firefox iOS we are trying to follow the desktop approach of allowing certain data URL media types.

@jumde
Copy link
Contributor

jumde commented Mar 31, 2020

@garvankeeley - Same plan: #2424 (comment)

Let us know if we're missing something.

@diracdeltas
Copy link
Member

any blockers here or can this be merged?

case WebKit::WebMouseEvent::TwoFingerTap:
return WKSyntheticClickTypeTwoFingerTap;
}*/
return decisionHandler(.cancel)
Copy link
Collaborator Author

@Brandon-T Brandon-T Apr 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note, the above code is done on purpose. Firefox desktop v75.0 (64-bit), MacOS blocks ALL synthetic clicks (touches/clicks that do not involve user interaction). For example test page which I hosted locally via python's flask framework:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Test Page</title>
</head>
<body>
    <p>
        <a href="data:text/html,<script>alert('hi');</script>">Should be Blocked</a>
        <a href="data:text/xhtml,<script>alert('hi');</script>">Should also be Blocked</a>
        <a href="data:application/xhtml,<script>alert('hi');</script>">How many are we going to block</a>
        <a href="data:image/svg+xml;base64,eyJ0ZXN0Ijoid2hhdGV2ZXIifQo=">I'm tired of blocking :(</a>
        <a href="data:video/mp4;base64,eyJ0ZXN0Ijoid2hhdGV2ZXIifQo=">Should do something</a>
        <a href="data:,">Should render blank plain text</a>
        <a href="data:application/json,{\"test\":\"yay\"}">Should do something</a>
        <a href="data:text/json;base64,PGh0bWw+PGJvZHkgc3R5bGU9J2JhY2tncm91bmQtY29sb3I6cmVkJz48L2JvZHk+PC9odG1sPgo=">I'm Valid!</a>
        <a href="data:text/plain;base64,PGh0bWw+PGJvZHkgc3R5bGU9J2JhY2tncm91bmQtY29sb3I6cmVkJz48L2JvZHk+PC9odG1sPgo=">I'm not plain..</a>
        <a href="data:application/something;base64,iVBORw0KGg==">Oh boy.. Not sure about this one</a>
    </p>

    <script>
        //Synthetically change the window TopLevelDomain via window.location or window.open
        setTimeout(function(){
            window.location = "data:text/html;base64,PGh0bWw+PGJvZHkgc3R5bGU9J2JhY2tncm91bmQtY29sb3I6cmVkJz48L2JvZHk+PC9odG1sPgo=";
            //window.open("data:text/html;base64,PGh0bWw+PGJvZHkgc3R5bGU9J2JhY2tncm91bmQtY29sb3I6cmVkJz48L2JvZHk+PC9odG1sPgo=");
        }, 2000);
    </script>
</body>
</html>

@jumde
Copy link
Contributor

jumde commented Apr 16, 2020

security review approved 👍

mediaType = headers.first ?? "text/plain"

let dataSegment = uri.index(infoSegment, offsetBy: 1)
//data = try! Data(contentsOf: URL(string: uri)!)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this line


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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to fallback to an empty data object?
Maybe throwing an error would be better, what do you think?


return decisionHandler(.cancel)
} catch {
return
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log error here

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Disable data URLs in top-level navigation Disabling Synthetic Clicks on Web Pages
7 participants