Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Commit

Permalink
Merge pull request #9879 from brave/default_unblock_3rd_cookies
Browse files Browse the repository at this point in the history
Add cookieException for google drive
  • Loading branch information
bsclifton committed Jul 25, 2017
1 parent 676ab6a commit 430025e
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 29 deletions.
64 changes: 43 additions & 21 deletions app/filtering.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const {updateElectronDownloadItem} = require('./browser/electronDownloadItem')
const {fullscreenOption} = require('./common/constants/settingsEnums')
const isThirdPartyHost = require('./browser/isThirdPartyHost')
var extensionState = require('./common/state/extensionState.js')
const {cookieExceptions, refererExceptions} = require('../js/data/siteHacks')

let appStore = null

Expand All @@ -46,9 +47,6 @@ let initializedPartitions = {}
const transparent1pxGif = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
const pdfjsOrigin = `chrome-extension://${config.PDFJSExtensionId}`

// Third party domains that require a valid referer to work
const refererExceptions = ['use.typekit.net', 'cloud.typography.com', 'www.moremorewin.net']

/**
* Maps partition name to the session object
*/
Expand Down Expand Up @@ -220,6 +218,47 @@ function registerForBeforeRedirect (session, partition) {
})
}

module.exports.applyCookieSetting = (requestHeaders, url, firstPartyUrl, isPrivate) => {
const cookieSetting = module.exports.isResourceEnabled(appConfig.resourceNames.COOKIEBLOCK, firstPartyUrl, isPrivate)
if (cookieSetting) {
const parsedTargetUrl = urlParse(url || '')
const parsedFirstPartyUrl = urlParse(firstPartyUrl)

if (cookieSetting === 'blockAllCookies' ||
isThirdPartyHost(parsedFirstPartyUrl.hostname, parsedTargetUrl.hostname)) {
let hasCookieException = false
const firstPartyOrigin = getOrigin(firstPartyUrl)
const targetOrigin = getOrigin(url)
if (cookieExceptions.hasOwnProperty(firstPartyOrigin)) {
const subResources = cookieExceptions[firstPartyOrigin]
for (let i = 0; i < subResources.length; ++i) {
if (subResources[i] === targetOrigin) {
hasCookieException = true
break
} else if (subResources[i].includes('*')) {
const regSubResource = new RegExp(subResources[i].replace('//', '\\/\\/').replace('*', '.*'), 'g')
if (targetOrigin.match(regSubResource)) {
hasCookieException = true
break
}
}
}
}
// Clear cookie and referer on third-party requests
if (requestHeaders['Cookie'] &&
firstPartyOrigin !== pdfjsOrigin && !hasCookieException) {
requestHeaders['Cookie'] = undefined
}
if (requestHeaders['Referer'] &&
!refererExceptions.includes(parsedTargetUrl.hostname)) {
requestHeaders['Referer'] = targetOrigin
}
}
}

return requestHeaders
}

/**
* Register for notifications for webRequest.onBeforeSendHeaders for
* a particular session.
Expand Down Expand Up @@ -266,25 +305,8 @@ function registerForBeforeSendHeaders (session, partition) {
}
}

const cookieSetting = module.exports.isResourceEnabled(appConfig.resourceNames.COOKIEBLOCK, firstPartyUrl, isPrivate)
if (cookieSetting) {
const parsedTargetUrl = urlParse(details.url || '')
const parsedFirstPartyUrl = urlParse(firstPartyUrl)
requestHeaders = module.exports.applyCookieSetting(requestHeaders, details.url, firstPartyUrl, isPrivate)

if (cookieSetting === 'blockAllCookies' ||
isThirdPartyHost(parsedFirstPartyUrl.hostname, parsedTargetUrl.hostname)) {
// Clear cookie and referer on third-party requests
if (requestHeaders['Cookie'] &&
getOrigin(firstPartyUrl) !== pdfjsOrigin) {
requestHeaders['Cookie'] = undefined
}
if (cookieSetting !== 'blockAllCookies' &&
requestHeaders['Referer'] &&
!refererExceptions.includes(parsedTargetUrl.hostname)) {
requestHeaders['Referer'] = getOrigin(details.url)
}
}
}
if (sendDNT) {
requestHeaders['DNT'] = '1'
}
Expand Down
14 changes: 9 additions & 5 deletions js/data/siteHacks.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@ const emptyDataURI = {
}

/**
* Holds an array of [Primary URL, subresource URL] to allow 3rd party cookies.
* Holds an map of {Primary URL: subresource URL} to allow 3rd party cookies.
* Subresource URL can be '*' or undefined to indicate all.
*/
module.exports.cookieExceptions = [
['https://inbox.google.com', 'https://hangouts.google.com'],
['https://mail.google.com', 'https://hangouts.google.com']
]
module.exports.cookieExceptions = {
'https://inbox.google.com': ['https://hangouts.google.com'],
'https://mail.google.com': ['https://hangouts.google.com'],
'https://drive.google.com': ['https://doc-*-docs.googleusercontent.com']
}

// Third party domains that require a valid referer to work
module.exports.refererExceptions = ['use.typekit.net', 'cloud.typography.com', 'www.moremorewin.net']

/**
* Holds an array of [Primary URL, subresource URL] to allow 3rd party localstorage.
Expand Down
9 changes: 6 additions & 3 deletions js/state/contentSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,12 @@ const siteSettingsToContentSettings = (currentSiteSettings, defaultContentSettin
contentSettings = addContentSettings(contentSettings, 'cookies', primaryPattern, '*', 'block')
contentSettings = addContentSettings(contentSettings, 'cookies', primaryPattern, primaryPattern, 'allow')
contentSettings = addContentSettings(contentSettings, 'referer', primaryPattern, '*', 'block')
cookieExceptions.forEach((exceptionPair) => {
contentSettings = addContentSettings(contentSettings, 'cookies', exceptionPair[0], exceptionPair[1], 'allow')
})
for (let key in cookieExceptions) {
const subResources = cookieExceptions[key]
for (let i = 0; i < subResources.length; ++i) {
contentSettings = addContentSettings(contentSettings, 'cookies', key, subResources[i], 'allow')
}
}
} else if (siteSetting.get('cookieControl') === 'blockAllCookies') {
contentSettings = addContentSettings(contentSettings, 'cookies', primaryPattern, '*', 'block')
contentSettings = addContentSettings(contentSettings, 'referer', primaryPattern, '*', 'block')
Expand Down
120 changes: 120 additions & 0 deletions test/unit/app/filteringTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* global describe, before, after, it */
const mockery = require('mockery')
const assert = require('assert')
const sinon = require('sinon')
const {cookieExceptions, refererExceptions} = require('../../../js/data/siteHacks')

require('../braveUnit')

describe('filtering unit tests', function () {
let filtering
const fakeElectron = require('../lib/fakeElectron')

before(function () {
mockery.enable({
warnOnReplace: false,
warnOnUnregistered: false,
useCleanCache: true
})
mockery.registerMock('electron', fakeElectron)
mockery.registerMock('./adBlock', {adBlockResourceName: 'adblock'})
filtering = require('../../../app/filtering')
})

after(function () {
mockery.disable()
})

describe('applyCookieSetting', function () {
describe('when cookieSetting === "blockAllCookies"', function () {
let isResourceEnabledStub
before(function () {
isResourceEnabledStub = sinon.stub(filtering, 'isResourceEnabled').returns('blockAllCookies')
})
after(function () {
isResourceEnabledStub.restore()
})

it('clears cookie field', function () {
const url = 'https://cdnp3.stackassets.com/574db2390a12942fcef927356dadc6f9955edea9/store/fe3eb8fc014a20f2d25810b3c4f4b5b0db8695adfd7e8953721a55c51b90/sale_7217_primary_image.jpg'
const firstPartyUrl = 'https://slashdot.org/'
const requestHeaders = {
Cookie: 'optimizelyEndUserId=oeu1491721215718r0.024789086462633003; __ssid=97b17d31-8f1b-4193-8914-df36e7b740f6; optimizelySegments=%7B%22300150879%22%3A%22false%22%2C%22300333436%22%3A%22gc%22%2C%22300387578%22%3A%22campaign%22%7D; optimizelyBuckets=%7B%7D; _pk_id.40.2105=8fca10ea565f58bf.1485982886.187.1499406000.1499405260.; _pk_ses.40.2105=*'
}
const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)

assert.equal(result.Cookie, undefined)
})

describe('when there is a cookie exception', function () {
it('keeps the cookie field', function () {
let cookieException = false
let firstPartyUrl = ''
let url = ''
for (let key in cookieExceptions) {
firstPartyUrl = key
const urls = cookieExceptions[key]
url = urls[0]
cookieException = true
break
}

assert(cookieException)

const requestHeaders = {
Cookie: 'optimizelyEndUserId=oeu1491721215718r0.024789086462633003; __ssid=97b17d31-8f1b-4193-8914-df36e7b740f6; optimizelySegments=%7B%22300150879%22%3A%22false%22%2C%22300333436%22%3A%22gc%22%2C%22300387578%22%3A%22campaign%22%7D; optimizelyBuckets=%7B%7D; _pk_id.40.2105=8fca10ea565f58bf.1485982886.187.1499406000.1499405260.; _pk_ses.40.2105=*'
}
const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)

assert.equal(result.Cookie, requestHeaders.Cookie)
})
it('wildcard cookie exception', function () {
// Specifically testing drive.google.com
const firstPartyUrl = 'https://drive.google.com'
const url = 'https://doc-0g-3g-docs.googleusercontent.com'

const requestHeaders = {
Cookie: 'optimizelyEndUserId=oeu1491721215718r0.024789086462633003; __ssid=97b17d31-8f1b-4193-8914-df36e7b740f6; optimizelySegments=%7B%22300150879%22%3A%22false%22%2C%22300333436%22%3A%22gc%22%2C%22300387578%22%3A%22campaign%22%7D; optimizelyBuckets=%7B%7D; _pk_id.40.2105=8fca10ea565f58bf.1485982886.187.1499406000.1499405260.; _pk_ses.40.2105=*'
}
const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)

assert.equal(result.Cookie, requestHeaders.Cookie)
})
})
})

describe('when cookieSetting === "block3rdPartyCookie"', function () {
let isResourceEnabledStub
before(function () {
isResourceEnabledStub = sinon.stub(filtering, 'isResourceEnabled').returns('block3rdPartyCookie')
})
after(function () {
isResourceEnabledStub.restore()
})

it('sets the referer to the origin', function () {
const url = 'https://cdnp3.stackassets.com/574db2390a12942fcef927356dadc6f9955edea9/store/fe3eb8fc014a20f2d25810b3c4f4b5b0db8695adfd7e8953721a55c51b90/sale_7217_primary_image.jpg'
const firstPartyUrl = 'https://slashdot.org/'
const requestHeaders = {
Referer: 'https://brave.com'
}
const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)

assert.equal(result.Referer, 'https://cdnp3.stackassets.com')
})

describe('when there is a referer exception', function () {
it('keeps the referer field', function () {
const url = 'https://' + refererExceptions[0]
const firstPartyUrl = 'https://slashdot.org/'
const requestHeaders = {
Referer: 'https://brave.com'
}
const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)

assert.equal(result.Referer, requestHeaders.Referer)
})
})
})
})
})

0 comments on commit 430025e

Please sign in to comment.