Skip to content

Commit fb3f28e

Browse files
committed
add 3rd party fingerprinting block option
fix brave#9029
1 parent ed41bc8 commit fb3f28e

File tree

17 files changed

+284
-65
lines changed

17 files changed

+284
-65
lines changed

app/extensions/brave/content/scripts/blockCanvasFingerprinting.js

+5
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ if (chrome.contentSettings.canvasFingerprinting == 'block') {
7575

7676
function reportBlock (type) {
7777
var script_url = getOriginatingScriptUrl()
78+
if (script_url) {
79+
script_url = stripLineAndColumnNumbers(script_url)
80+
} else {
81+
script_url = window.location.href
82+
}
7883
var msg = {
7984
type,
8085
scriptUrl: stripLineAndColumnNumbers(script_url)

app/extensions/brave/locales/en-US/bravery.properties

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
blockAds=Block Ads
22
allowAdsAndTracking=Allow Ads and Tracking
33
block3rdPartyCookie=Block 3rd Party Cookies
4+
block3rdPartyFingerprinting=Block 3rd Party Fingerprinting
45
httpsEverywhere=HTTPS Everywhere
56
noScript=Block Scripts
67
noScriptPref=Block Scripts (will break many sites)
@@ -10,7 +11,9 @@ fingerprintingProtection=Fingerprinting Protection
1011
adControl=Ad Control
1112
cookieControl=Cookie Control
1213
allowAllCookies=Allow all cookies
14+
allowAllFingerprinting=Allow all fingerprinting
1315
blockAllCookies=Block all cookies
16+
blockAllFingerprinting=Block all fingerprinting
1417
adBlock=Ad Block
1518
showBraveAds=Show Brave Ads
1619
adsBlocked={[plural(blockedAdCount)]}

app/extensions/brave/locales/en-US/preferences.properties

-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ offerSearchSuggestions=Autocomplete search term as you type
203203
doNotTrackTitle=Do Not Track
204204
doNotTrack=Send a 'Do Not Track' header with browsing requests *
205205
fullscreenContent=Full Screen Content
206-
blockCanvasFingerprinting=Fingerprinting Protection (may break some sites)
207206
advancedSettingsTitle=Advanced Settings for Brave Payments
208207
advancedSettingsIcon.title=Advanced Settings
209208
ledgerRecoveryTitle=Recover your Brave wallet

app/renderer/components/main/braveryPanel.js

+42-17
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ class BraveryPanel extends React.Component {
212212
props.noScriptEnabled = braverySettings.noScript
213213
props.httpsEnabled = braverySettings.httpsEverywhere
214214
props.adControl = braverySettings.adControl
215-
props.isFpEnabled = braverySettings.fingerprintingProtection
215+
props.isFpEnabled = braverySettings.fingerprintingProtection !== 'allowAllFingerprinting'
216+
props.fingerprintingProtection = braverySettings.fingerprintingProtection
216217
props.cookieControl = braverySettings.cookieControl
217218
props.safeBrowsing = braverySettings.safeBrowsing
218219
props.isCompactBraveryPanel = getSetting(settings.COMPACT_BRAVERY_PANEL)
@@ -515,7 +516,7 @@ class BraveryPanel extends React.Component {
515516

516517
<SwitchControl className={css(
517518
!this.props.isCompactBraveryPanel && gridStyles.row3col1,
518-
this.props.isCompactBraveryPanel && gridStyles.row5col1,
519+
this.props.isCompactBraveryPanel && gridStyles.row7col1,
519520
this.props.isCompactBraveryPanel && styles.braveryPanel_compact__body__advanced__control__switchControl
520521
)}
521522
onClick={this.onToggleHTTPSE}
@@ -527,7 +528,7 @@ class BraveryPanel extends React.Component {
527528

528529
<SwitchControl className={css(
529530
!this.props.isCompactBraveryPanel && gridStyles.row4col1,
530-
this.props.isCompactBraveryPanel && gridStyles.row6col1,
531+
this.props.isCompactBraveryPanel && gridStyles.row8col1,
531532
this.props.isCompactBraveryPanel && styles.braveryPanel_compact__body__advanced__control__switchControl
532533
)}
533534
onClick={this.onToggleNoScript}
@@ -559,24 +560,48 @@ class BraveryPanel extends React.Component {
559560
</BraveryPanelDropdown>
560561
</div>
561562

562-
<SwitchControl className={css(
563+
<div data-l10n-id='fingerprintingProtection' className={css(
564+
!this.props.shieldsUp && styles.braveryPanel__body__advanced__control__forms__title_disabled,
563565
!this.props.isCompactBraveryPanel && gridStyles.row3col2,
564-
this.props.isCompactBraveryPanel && gridStyles.row7col1,
565-
this.props.isCompactBraveryPanel && styles.braveryPanel_compact__body__advanced__control__switchControl
566-
)}
567-
customInfoButtonClassName={css(styles.braveryPanel__body__advanced__control__switchControl__infoButton)}
568-
onClick={this.onToggleFp}
569-
rightl10nId='fingerprintingProtection'
570-
checkedOn={this.props.isFpEnabled}
571-
disabled={!this.props.shieldsUp}
572-
onInfoClick={this.onInfoClick}
573-
infoTitle={config.fingerprintingInfoUrl}
574-
testId='fingerprintingProtectionSwitch'
566+
!this.props.isCompactBraveryPanel && styles.braveryPanel__body__advanced__control__forms__title,
567+
this.props.isCompactBraveryPanel && gridStyles.row5col1,
568+
this.props.isCompactBraveryPanel && styles.braveryPanel_compact__body__advanced__control__forms__title
569+
)} />
570+
<span className={cx({
571+
[css(gridStyles.row3col2)]: !this.props.isCompactBraveryPanel,
572+
[css(gridStyles.row5col1)]: this.props.isCompactBraveryPanel,
573+
[css(styles.braveryPanel__body__advanced__control__forms__title_disabled)]: !this.props.shieldsUp,
574+
[css(styles.braveryPanel_compact__body__advanced__control__forms__title)]: this.props.isCompactBraveryPanel,
575+
[css(styles.braveryPanel__body__advanced__control__forms__title)]: !this.props.isCompactBraveryPanel,
576+
fa: true,
577+
pullRight: true,
578+
'fa-question-circle': true
579+
})}
580+
title={config.fingerprintingInfoUrl}
581+
onClick={this.onInfoClick}
575582
/>
576583

577-
<SwitchControl className={css(
584+
<div className={css(
585+
!this.props.shieldsUp && styles.braveryPanel__body__advanced__control__forms__dropdown_disabled,
578586
!this.props.isCompactBraveryPanel && gridStyles.row4col2,
579-
this.props.isCompactBraveryPanel && gridStyles.row8col1,
587+
!this.props.isCompactBraveryPanel && styles.braveryPanel__body__advanced__control__forms__dropdown,
588+
this.props.isCompactBraveryPanel && gridStyles.row6col1,
589+
this.props.isCompactBraveryPanel && styles.braveryPanel_compact__body__advanced__control__forms__dropdown
590+
)}>
591+
<BraveryPanelDropdown
592+
data-test-id='fpControl'
593+
value={this.props.fingerprintingProtection}
594+
onChange={this.onToggleFp}
595+
disabled={!this.props.shieldsUp}>
596+
<option data-l10n-id='block3rdPartyFingerprinting' data-test-id='block3rdPartyFingerprinting' value='block3rdPartyFingerprinting' />
597+
<option data-l10n-id='allowAllFingerprinting' data-test-id='allowAllFingerprinting' value='allowAllFingerprinting' />
598+
<option data-l10n-id='blockAllFingerprinting' data-test-id='blockAllFingerprinting' value='blockAllFingerprinting' />
599+
</BraveryPanelDropdown>
600+
</div>
601+
602+
<SwitchControl className={css(
603+
!this.props.isCompactBraveryPanel && gridStyles.row5col1,
604+
this.props.isCompactBraveryPanel && gridStyles.row9col1,
580605
this.props.isCompactBraveryPanel && styles.braveryPanel_compact__body__advanced__control__switchControl
581606
)}
582607
onClick={this.onToggleSafeBrowsing}

app/sessionStore.js

+22
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,28 @@ module.exports.runPreMigrations = (data) => {
675675
}
676676

677677
module.exports.runPostMigrations = (data) => {
678+
// fingerprinting protection migration
679+
if (typeof data.settings['privacy.block-canvas-fingerprinting'] !== 'boolean') {
680+
return data
681+
}
682+
try {
683+
const siteSettings = data.siteSettings
684+
if (siteSettings) {
685+
for (let host in siteSettings) {
686+
if (siteSettings[host].fingerprintingProtection === true) {
687+
siteSettings[host].fingerprintingProtection = 'blockAllFingerprinting'
688+
} else if (siteSettings[host].fingerprintingProtection === false) {
689+
siteSettings[host].fingerprintingProtection = 'allowAllFingerprinting'
690+
}
691+
}
692+
}
693+
data['fingerprintingProtectionAll'] = {
694+
enabled: data.settings['privacy.block-canvas-fingerprinting']
695+
}
696+
delete data.settings['privacy.block-canvas-fingerprinting']
697+
} catch (e) {
698+
console.log('fingerprinting protection migration failed', e)
699+
}
678700
return data
679701
}
680702

docs/state.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ AppStore
150150
}
151151
} // the unique id of the extension
152152
},
153+
fingerprintingProtection: {
154+
enabled: boolean // enable 3p fingerprinting blocking. default true.
155+
},
156+
fingerprintingProtectionAll: {
157+
enabled: boolean // enable all fingerprinting blocking. default false.
158+
},
153159
firstRunTimestamp: integer,
154160
flash: {
155161
enabled: boolean // enable flash
@@ -253,7 +259,6 @@ AppStore
253259
'payments.notificationTryPaymentsDismissed': boolean, // true if you dismiss the message or enable Payments
254260
'privacy.autocomplete.history-size': number, // number of autocomplete entries to keep
255261
'privacy.autofill-enabled': boolean, // true to enable autofill
256-
'privacy.block-canvas-fingerprinting': boolean, // canvas fingerprinting defense
257262
'privacy.bookmark-suggestions': boolean, // auto suggest for bookmarks enabled
258263
'privacy.do-not-track': boolean, // whether DNT is 1
259264
'privacy.history-suggestions': boolean, // auto suggest for history enabled
@@ -292,7 +297,7 @@ AppStore
292297
[hostPattern]: {
293298
adControl: string, // (showBraveAds | blockAds | allowAdsAndTracking)
294299
cookieControl: string, // (block3rdPartyCookie | allowAllCookies | blockAllCookies)
295-
fingerprintingProtection: boolean,
300+
fingerprintingProtection: string, // (block3rdPartyFingerprinting | allowAllFingerprinting | blockAllFingerprinting)
296301
flash: (number|boolean), // approval expiration time if allowed, false if never allow
297302
fullscreenPermission: boolean,
298303
geolocationPermission: boolean,

js/about/preferences.js

+16-2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ const searchProviders = require('../data/searchProviders')
4646
const adblock = appConfig.resourceNames.ADBLOCK
4747
const cookieblock = appConfig.resourceNames.COOKIEBLOCK
4848
const cookieblockAll = appConfig.resourceNames.COOKIEBLOCK_ALL
49+
const fingerprintingProtection = appConfig.resourceNames.FINGERPRINTING_PROTECTION
50+
const fingerprintingProtectionAll = appConfig.resourceNames.FINGERPRINTING_PROTECTION_ALL
4951
const adInsertion = appConfig.resourceNames.AD_INSERTION
5052
const trackingProtection = appConfig.resourceNames.TRACKING_PROTECTION
5153
const httpsEverywhere = appConfig.resourceNames.HTTPS_EVERYWHERE
@@ -88,7 +90,7 @@ const braveryPermissionNames = {
8890
'cookieControl': ['string'],
8991
'safeBrowsing': ['boolean'],
9092
'httpsEverywhere': ['boolean'],
91-
'fingerprintingProtection': ['boolean'],
93+
'fingerprintingProtection': ['string'],
9294
'noScript': ['boolean', 'number']
9395
}
9496

@@ -488,6 +490,10 @@ class ShieldsTab extends ImmutableComponent {
488490
aboutActions.setResourceEnabled(cookieblock, e.target.value === 'block3rdPartyCookie')
489491
aboutActions.setResourceEnabled(cookieblockAll, e.target.value === 'blockAllCookies')
490492
}
493+
onChangeFingerprintingProtection (e) {
494+
aboutActions.setResourceEnabled(fingerprintingProtection, e.target.value === 'block3rdPartyFingerprinting')
495+
aboutActions.setResourceEnabled(fingerprintingProtectionAll, e.target.value === 'blockAllFingerprinting')
496+
}
491497
onToggleSetting (setting, e) {
492498
aboutActions.setResourceEnabled(setting, e.target.value)
493499
}
@@ -513,10 +519,18 @@ class ShieldsTab extends ImmutableComponent {
513519
<option data-l10n-id='blockAllCookies' value='blockAllCookies' />
514520
</SettingDropdown>
515521
</SettingItem>
522+
<SettingItem dataL10nId='fingerprintingProtection'>
523+
<SettingDropdown
524+
value={this.props.braveryDefaults.get('fingerprintingProtection')}
525+
onChange={this.onChangeFingerprintingProtection}>
526+
<option data-l10n-id='block3rdPartyFingerprinting' value='block3rdPartyFingerprinting' />
527+
<option data-l10n-id='allowAllFingerprinting' value='allowAllFingerprinting' />
528+
<option data-l10n-id='blockAllFingerprinting' value='blockAllFingerprinting' />
529+
</SettingDropdown>
530+
</SettingItem>
516531
<SettingCheckbox checked={this.props.braveryDefaults.get('httpsEverywhere')} dataL10nId='httpsEverywhere' onChange={this.onToggleHTTPSE} />
517532
<SettingCheckbox checked={this.props.braveryDefaults.get('safeBrowsing')} dataL10nId='safeBrowsing' onChange={this.onToggleSafeBrowsing} />
518533
<SettingCheckbox checked={this.props.braveryDefaults.get('noScript')} dataL10nId='noScriptPref' onChange={this.onToggleNoScript} />
519-
<SettingCheckbox dataL10nId='blockCanvasFingerprinting' prefKey={settings.BLOCK_CANVAS_FINGERPRINTING} settings={this.props.settings} onChangeSetting={this.props.onChangeSetting} />
520534
{/* TODO: move this inline style to Aphrodite once refactored */}
521535
<div style={{marginTop: '15px'}}>
522536
<BrowserButton

js/constants/appConfig.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ module.exports = {
2424
SAFE_BROWSING: 'safeBrowsing',
2525
HTTPS_EVERYWHERE: 'httpsEverywhere',
2626
TRACKING_PROTECTION: 'trackingProtection',
27+
FINGERPRINTING_PROTECTION: 'fingerprintingProtection', // block 3p fingerprinting
28+
FINGERPRINTING_PROTECTION_ALL: 'fingerprintingProtectionAll', // block all fingerprinting
2729
AD_INSERTION: 'adInsertion',
2830
NOSCRIPT: 'noScript',
2931
FLASH: 'flash',
@@ -40,6 +42,12 @@ module.exports = {
4042
cookieblockAll: {
4143
enabled: false
4244
},
45+
fingerprintingProtection: {
46+
enabled: true
47+
},
48+
fingerprintingProtectionAll: {
49+
enabled: false
50+
},
4351
noScript: {
4452
enabled: false,
4553
twitterRedirectUrl: 'https://mobile.twitter.com/i/nojs_router'
@@ -148,7 +156,6 @@ module.exports = {
148156
'privacy.topsite-suggestions': true,
149157
'privacy.opened-tab-suggestions': true,
150158
'privacy.autocomplete.history-size': 500,
151-
'privacy.block-canvas-fingerprinting': false,
152159
'bookmarks.toolbar.show': false,
153160
'bookmarks.toolbar.showFavicon': false,
154161
'bookmarks.toolbar.showOnlyFavicon': false,

js/constants/settings.js

-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ const settings = {
3636
OPENED_TAB_SUGGESTIONS: 'privacy.opened-tab-suggestions',
3737
AUTOCOMPLETE_HISTORY_SIZE: 'privacy.autocomplete.history-size',
3838
DO_NOT_TRACK: 'privacy.do-not-track',
39-
BLOCK_CANVAS_FINGERPRINTING: 'privacy.block-canvas-fingerprinting',
4039
// Security Tab
4140
ACTIVE_PASSWORD_MANAGER: 'security.passwords.active-password-manager',
4241
SHUTDOWN_CLEAR_HISTORY: 'shutdown.clear-history',

js/state/contentSettings.js

+44-6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ const getDefaultUserPrefContentSettings = (braveryDefaults, appSettings, appConf
7575
primaryPattern: '*'
7676
}],
7777
cookies: getDefault3rdPartyStorageSettings(braveryDefaults, appSettings, appConfig),
78+
canvasFingerprinting: getDefaultFingerprintingSetting(braveryDefaults),
7879
referer: [{
7980
setting: braveryDefaults.get('cookieControl') !== 'allowAllCookies' ? 'block' : 'allow',
8081
primaryPattern: '*'
@@ -100,10 +101,6 @@ const getDefaultUserPrefContentSettings = (braveryDefaults, appSettings, appConf
100101
secondaryPattern: '*',
101102
primaryPattern: 'chrome-extension://*'
102103
}],
103-
canvasFingerprinting: [{
104-
setting: braveryDefaults.get('fingerprintingProtection') ? 'block' : 'allow',
105-
primaryPattern: '*'
106-
}],
107104
runInsecureContent: [{
108105
setting: 'block',
109106
primaryPattern: '*'
@@ -170,6 +167,40 @@ const getDefaultPluginSettings = (braveryDefaults, appSettings, appConfig) => {
170167
]
171168
}
172169

170+
const getDefaultFingerprintingSetting = (braveryDefaults, appSettings, appConfig) => {
171+
braveryDefaults = makeImmutable(braveryDefaults)
172+
if (braveryDefaults.get('fingerprintingProtection') === 'block3rdPartyFingerprinting') {
173+
return [
174+
{
175+
setting: 'block',
176+
primaryPattern: '*',
177+
secondaryPattern: '*'
178+
},
179+
{
180+
setting: 'allow',
181+
primaryPattern: '*',
182+
secondaryPattern: '[firstParty]'
183+
}
184+
]
185+
} else if (braveryDefaults.get('fingerprintingProtection') === 'blockAllFingerprinting') {
186+
return [
187+
{
188+
setting: 'block',
189+
primaryPattern: '*',
190+
secondaryPattern: '*'
191+
}
192+
]
193+
} else {
194+
return [
195+
{
196+
setting: 'allow',
197+
primaryPattern: '*',
198+
secondaryPattern: '*'
199+
}
200+
]
201+
}
202+
}
203+
173204
const getDefault3rdPartyStorageSettings = (braveryDefaults, appSettings, appConfig) => {
174205
braveryDefaults = makeImmutable(braveryDefaults)
175206
if (braveryDefaults.get('cookieControl') === 'block3rdPartyCookie') {
@@ -278,8 +309,15 @@ const siteSettingsToContentSettings = (currentSiteSettings, defaultContentSettin
278309
contentSettings = addContentSettings(contentSettings, 'referer', primaryPattern, '*', 'allow')
279310
}
280311
}
281-
if (typeof siteSetting.get('fingerprintingProtection') === 'boolean') {
282-
contentSettings = addContentSettings(contentSettings, 'canvasFingerprinting', primaryPattern, '*', siteSetting.get('fingerprintingProtection') ? 'block' : 'allow')
312+
if (siteSetting.get('fingerprintingProtection')) {
313+
if (siteSetting.get('fingerprintingProtection') === 'block3rdPartyFingerprinting') {
314+
contentSettings = addContentSettings(contentSettings, 'canvasFingerprinting', primaryPattern, '*', 'block')
315+
contentSettings = addContentSettings(contentSettings, 'canvasFingerprinting', primaryPattern, '[firstParty]', 'allow')
316+
} else if (siteSetting.get('fingerprintingProtection') === 'blockAllFingerprinting') {
317+
contentSettings = addContentSettings(contentSettings, 'canvasFingerprinting', primaryPattern, '*', 'block')
318+
} else {
319+
contentSettings = addContentSettings(contentSettings, 'canvasFingerprinting', primaryPattern, '*', 'allow')
320+
}
283321
}
284322
if (siteSetting.get('adControl')) {
285323
contentSettings = addContentSettings(contentSettings, 'adInsertion', primaryPattern, '*', siteSetting.get('adControl') === 'showBraveAds' ? 'allow' : 'block')

js/state/siteSettings.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ module.exports.braveryDefaults = (appState, appConfig) => {
1717
let blockTracking = defaults[appConfig.resourceNames.TRACKING_PROTECTION] || false
1818
let blockCookies = defaults[appConfig.resourceNames.COOKIEBLOCK] || false
1919
let blockCookiesAll = defaults[appConfig.resourceNames.COOKIEBLOCK_ALL] || false
20+
let blockFingerprinting = defaults[appConfig.resourceNames.FINGERPRINTING_PROTECTION] || false
21+
let blockFingerprintingAll = defaults[appConfig.resourceNames.FINGERPRINTING_PROTECTION_ALL] || false
22+
2023
defaults.adControl = 'allowAdsAndTracking'
2124
if (blockAds && replaceAds && blockTracking) {
2225
defaults.adControl = 'showBraveAds'
@@ -27,13 +30,10 @@ module.exports.braveryDefaults = (appState, appConfig) => {
2730
if (blockCookiesAll) {
2831
defaults.cookieControl = 'blockAllCookies'
2932
}
30-
31-
// TODO(bridiver) this should work just like the other bravery settings
32-
let fingerprintingProtection = appState.get('settings').get('privacy.block-canvas-fingerprinting')
33-
if (typeof fingerprintingProtection !== 'boolean') {
34-
fingerprintingProtection = appConfig.defaultSettings['privacy.block-canvas-fingerprinting']
33+
defaults.fingerprintingProtection = blockFingerprinting ? 'block3rdPartyFingerprinting' : 'allowAllFingerprinting'
34+
if (blockFingerprintingAll) {
35+
defaults.fingerprintingProtection = 'blockAllFingerprinting'
3536
}
36-
defaults.fingerprintingProtection = fingerprintingProtection
3737
return defaults
3838
}
3939

@@ -96,10 +96,10 @@ module.exports.activeSettings = (siteSettings, appState, appConfig) => {
9696

9797
settings.fingerprintingProtection = (() => {
9898
if (settings.shieldsUp === false) {
99-
return false
99+
return 'allowAllFingerprinting'
100100
}
101101
if (siteSettings) {
102-
if (typeof siteSettings.get('fingerprintingProtection') === 'boolean') {
102+
if (typeof siteSettings.get('fingerprintingProtection') === 'string') {
103103
return siteSettings.get('fingerprintingProtection')
104104
}
105105
}

0 commit comments

Comments
 (0)