-
Notifications
You must be signed in to change notification settings - Fork 973
refactor isThirdPartyHost and block referer based on base domain #13820
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,22 +3,28 @@ | |
* You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
const getBaseDomain = require('../../js/lib/baseDomain').getBaseDomain | ||
const ip = require('ip') | ||
|
||
/** | ||
* baseContextHost {string} - The base host to check against | ||
* testHost {string} - The host to check | ||
* Checks if two hosts are third party. Subdomains count as first-party to the | ||
* parent domain. Uses hostname (no port). | ||
* @param {host1} string - First hostname to compare | ||
* @param {host2} string - Second hostname to compare | ||
*/ | ||
const isThirdPartyHost = (baseContextHost, testHost) => { | ||
// TODO: Always return true if these are IP addresses that aren't the same | ||
if (!testHost || !baseContextHost) { | ||
const isThirdPartyHost = (host1, host2) => { | ||
if (!host1 || !host2) { | ||
return true | ||
} | ||
const documentDomain = getBaseDomain(baseContextHost) | ||
if (testHost.length > documentDomain.length) { | ||
return (testHost.substr(testHost.length - documentDomain.length - 1) !== '.' + documentDomain) | ||
} else { | ||
return (testHost !== documentDomain) | ||
if (host1 === host2) { | ||
return false | ||
} | ||
|
||
if (ip.isV4Format(host1) || ip.isV4Format(host2)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. &&? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jumde the problem with && is that |
||
// '127.0.0.1' and '::7f00:1' are actually equal, but ignore such cases for now | ||
return host1 !== host2 | ||
} | ||
|
||
return getBaseDomain(host1) !== getBaseDomain(host2) | ||
} | ||
|
||
module.exports = isThirdPartyHost |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,10 @@ const checkASCII = function (str) { | |
* Returns base domain for specified host based on Public Suffix List. | ||
* Derived from Privacy Badger Chrome <https://github.com/EFForg/privacybadger>, | ||
* Copyright (C) 2015 Electronic Frontier Foundation and other contributors | ||
* @param {string} hostname The name of the host to get the base domain for | ||
* TODO: Consider refactoring this into isThirdPartyHost since it's only used | ||
* for that. | ||
* @param {string} hostname The name of the host to get the base domain for. | ||
* The caller must validate that this is a valid, non-IP hostname string!! | ||
*/ | ||
|
||
module.exports.getBaseDomain = function (hostname) { | ||
|
@@ -44,6 +47,11 @@ module.exports.getBaseDomain = function (hostname) { | |
return baseDomain | ||
} | ||
|
||
// If the hostname is a TLD, return '' for the base domain | ||
if (hostname in publicSuffixes) { | ||
return '' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. previously for an effective TLD like note that some eTLDs like |
||
} | ||
|
||
// search through PSL | ||
var prevDomains = [] | ||
var curDomain = hostname | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,11 +12,40 @@ describe('isThirdPartyHost test', function () { | |
}) | ||
it('A subdomain URL should not be third party', function () { | ||
assert.ok(!isThirdPartyHost(braveHost, 'ragu.brave.com')) | ||
assert.ok(!isThirdPartyHost('ragu.brave.com', braveHost)) | ||
}) | ||
it('A 2nd level subdomain URL should not be third party', function () { | ||
assert.ok(!isThirdPartyHost(braveHost, 'foo.bar.brave.com')) | ||
assert.ok(!isThirdPartyHost('foo.bar.brave.com', braveHost)) | ||
}) | ||
it('Unrelated URLs should be third party', function () { | ||
assert.ok(isThirdPartyHost(braveHost, 'ragu.com')) | ||
assert.ok(isThirdPartyHost('ragu.com', braveHost)) | ||
}) | ||
it('Checks subdomains properly', function () { | ||
assert.ok(isThirdPartyHost(braveHost, 'brave.ragu.com')) | ||
assert.ok(isThirdPartyHost('brave.ragu.com', braveHost)) | ||
}) | ||
it('Handles multi-part TLDs', function () { | ||
assert.ok(isThirdPartyHost('diracdeltas.github.io', 'brave.github.io')) | ||
assert.ok(isThirdPartyHost('github.io', 'brave.github.io')) | ||
assert.ok(!isThirdPartyHost('github.io', 'github.io')) | ||
assert.ok(isThirdPartyHost('brave.github.io', 'github.io')) | ||
assert.ok(isThirdPartyHost('brave.co.uk', 'example.co.uk')) | ||
}) | ||
it('Handles IPv4', function () { | ||
assert.ok(isThirdPartyHost('172.217.6.46', '173.217.6.46')) | ||
assert.ok(!isThirdPartyHost('172.217.6.46', '172.217.6.46')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test equivalent decimal representations of IP addresses? No harm if we say that 127.1 and 127.0.0.1, or 1.2.3.4 and 001.002.003.004, are distinct, but we should be explicitly intentional about it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's clear from https://github.com/brave/browser-laptop/pull/13820/files#diff-3e19062054041e338c28b2593b82e8d9R23 that this is not intended to handle IP representations that are equivalent but don't have the same string representation for now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or are you suggesting adding a test for the equivalent case returning third party so that it's explicit based on tests what the behavior should be? i can do that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ^ probably best to do in a follow-up PR since it's non-critical and adding it here would dismiss the existing reviews |
||
}) | ||
it('Handles IPv6', function () { | ||
assert.ok(!isThirdPartyHost('[2001:db8:85a3::8a2e:370:7334]', '[2001:db8:85a3::8a2e:370:7334]')) | ||
assert.ok(!isThirdPartyHost('2001:db8:85a3::8a2e:370:7334', '2001:db8:85a3::8a2e:370:7334')) | ||
assert.ok(isThirdPartyHost('[2001:db8:85a3::8a2e:370:7334]', '[2002:db8:85a3::8a2e:370:7334]')) | ||
assert.ok(isThirdPartyHost('2001:db8:85a3::8a2e:370:7334', '2002:db8:85a3::8a2e:370:7334')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test v4-mapped IPv6 addresses vs equivalent IPv4 addresses? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
}) | ||
it('Handles null', function () { | ||
assert.ok(isThirdPartyHost('', '')) | ||
assert.ok(isThirdPartyHost(null, null)) | ||
assert.ok(isThirdPartyHost('', null)) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* 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/. */ | ||
/* global describe, it */ | ||
|
||
const {getBaseDomain} = require('../../../../js/lib/baseDomain') | ||
const assert = require('assert') | ||
|
||
require('../../braveUnit') | ||
|
||
describe('getBaseDomain', function () { | ||
it('regular domain and subdomains', function () { | ||
const domain = 'brave.com' | ||
assert.equal(domain, getBaseDomain('brave.com')) | ||
assert.equal(domain, getBaseDomain('test.brave.com')) | ||
assert.equal(domain, getBaseDomain('foo.test.brave.com')) | ||
}) | ||
it('international domains', function () { | ||
assert.equal('brave.comа', getBaseDomain('www.brave.xn--com-8cd')) | ||
assert.equal('brave.\u9ce5\u53d6.jp', getBaseDomain('\u9ce5\u53d6.jp.brave.\u9ce5\u53d6.jp')) | ||
assert.equal('ebаy.com', getBaseDomain('xn--eby-7cd.com')) | ||
}) | ||
it('multi-part domains', function () { | ||
assert.equal('diracdeltas.github.io', getBaseDomain('diracdeltas.github.io')) | ||
assert.equal('diracdeltas.github.io', getBaseDomain('foo.diracdeltas.github.io')) | ||
assert.equal('bar.ginoza.okinawa.jp', getBaseDomain('foo.bar.ginoza.okinawa.jp')) | ||
assert.equal('brave.co.uk', 'brave.co.uk') | ||
}) | ||
it('tlds', function () { | ||
assert.equal('', getBaseDomain('github.io')) | ||
assert.equal('', getBaseDomain('co.uk')) | ||
}) | ||
it('non-hostname inputs', function () { | ||
assert.equal('', getBaseDomain('')) | ||
assert.equal('hello world', getBaseDomain('hello world')) | ||
assert.equal('[2001:0db8:85a3:0000:0000:8a2e:0370:7334]', getBaseDomain('[2001:0db8:85a3:0000:0000:8a2e:0370:7334]')) | ||
assert.equal('http://2001::7334', getBaseDomain('http://2001::7334')) | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be clear: This is supposed to be the complement of an equivalence relation now, yes? I.e., its complement is supposed to be transitive, reflexive, and symmetric? Can this be noted in the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure the previous implementation's complement was also transitive, reflexive, and symmetric (at least it was supposed to be), but this refactoring makes those properties more obvious