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

Commit

Permalink
restore noscript allow once & allow temp when noscript is globally on
Browse files Browse the repository at this point in the history
if noscript is on for a site only instead of globally, this feature is not
available because it is more complicated to implement and because it is less
useful for privacy (since changing shield settings is not possible in
private tabs anyway).

fix #2745
fix #3835

Auditors: @ayumi

Test Plan:
1. turn on 'block scripts' in preferences
2. go to apple.com, click noscript icon, choose 'allow'. verify that scripts are allowed.
3. open private tab, go to bing.com, click noscript icon, verify that 'allow this time'is the only option. click it and verify that scripts are allowed.
4. navigate the private tab to google.com and then back to bing.com. verify that scripts are blocked on both sites.
5. go to google.com in a regular tab and choose 'allow until restart'. verify that scripts are allowed.
6. restart browser and go to about:preferences#shields. verify that only apple.com is listed as an exception.
  • Loading branch information
diracdeltas committed Sep 30, 2016
1 parent 61f0021 commit ec065b9
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 34 deletions.
3 changes: 2 additions & 1 deletion app/extensions/brave/locales/en-US/preferences.properties
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ protocolRegistrationPermission=Protocol registration
shieldsUp=All Brave Shields
ledgerPaymentsShown=Brave Payments
flash=Run Adobe Flash Player
flashAllowOnce=Allow once
allowOnce=Allow once
allowUntilRestart=Allow until restart
flashAllowAlways=Allow until {{time}}
alwaysAllow=Always allow
alwaysDeny=Always deny
Expand Down
10 changes: 9 additions & 1 deletion app/sessionStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,23 @@ module.exports.cleanAppData = (data, isShutdown) => {
data.perWindowState.forEach((perWindowState) =>
module.exports.cleanPerWindowData(perWindowState, isShutdown))
}
// Delete expired Flash approvals
// Delete expired Flash and NoScript allow-once approvals
let now = Date.now()
for (var host in data.siteSettings) {
let expireTime = data.siteSettings[host].flash
if (typeof expireTime === 'number' && expireTime < now) {
delete data.siteSettings[host].flash
}
let noScript = data.siteSettings[host].noScript
if (typeof noScript === 'number') {
delete data.siteSettings[host].noScript
}
// Don't write runInsecureContent to session
delete data.siteSettings[host].runInsecureContent
// If the site setting is empty, delete it for privacy
if (Object.keys(data.siteSettings[host]).length === 0) {
delete data.siteSettings[host]
}
}
if (data.sites) {
const clearHistory = isShutdown && getSetting(settings.SHUTDOWN_CLEAR_HISTORY) === true
Expand Down
3 changes: 2 additions & 1 deletion docs/state.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ AppStore
adControl: string, // (showBraveAds | blockAds | allowAdsAndTracking)
cookieControl: string, // (block3rdPartyCookie | allowAllCookies)
safeBrowsing: boolean,
noScript: boolean,
noScript: (number|boolean), // true = block scripts, false = allow, 0 = allow once, 1 = allow until restart
httpsEverywhere: boolean,
fingerprintingProtection: boolean,
flash: (number|boolean), // approval expiration time if allowed, false if never allow
Expand All @@ -79,6 +79,7 @@ AppStore
},
temporarySiteSettings: {
// Same as above but never gets written to disk
// XXX: This was intended for Private Browsing but is currently unused.
},
visits: [{
location: string,
Expand Down
10 changes: 8 additions & 2 deletions js/about/preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const braveryPermissionNames = {
'safeBrowsing': ['boolean'],
'httpsEverywhere': ['boolean'],
'fingerprintingProtection': ['boolean'],
'noScript': ['boolean']
'noScript': ['boolean', 'number']
}

const changeSetting = (cb, key, e) => {
Expand Down Expand Up @@ -1049,7 +1049,7 @@ class SitePermissionsPage extends React.Component {
if (name === 'flash') {
if (granted === 1) {
// Flash is allowed just one time
statusText = 'flashAllowOnce'
statusText = 'allowOnce'
} else if (granted === false) {
// Flash installer is never intercepted
statusText = 'alwaysDeny'
Expand All @@ -1060,6 +1060,12 @@ class SitePermissionsPage extends React.Component {
time: new Date(granted).toLocaleString()
}
}
} else if (name === 'noScript' && typeof granted === 'number') {
if (granted === 1) {
statusText = 'allowUntilRestart'
} else if (granted === 0) {
statusText = 'allowOnce'
}
} else if (typeof granted === 'string') {
statusText = granted
} else if (!this.props.defaults) {
Expand Down
19 changes: 12 additions & 7 deletions js/components/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,21 +200,26 @@ class Frame extends ImmutableComponent {
return false
}

expireFlash (origin) {
expireContentSettings (origin) {
// Expired Flash settings should be deleted when the webview is
// navigated or closed.
// navigated or closed. Same for NoScript's allow-once option.
const activeSiteSettings = getSiteSettingsForHostPattern(this.props.allSiteSettings,
origin)
if (activeSiteSettings && typeof activeSiteSettings.get('flash') === 'number') {
if (!activeSiteSettings) {
return
}
if (typeof activeSiteSettings.get('flash') === 'number') {
if (activeSiteSettings.get('flash') < Date.now()) {
// Expired entry. Remove it.
appActions.removeSiteSetting(origin, 'flash')
}
}
if (activeSiteSettings.get('noScript') === 0) {
appActions.removeSiteSetting(origin, 'noScript')
}
}

componentWillUnmount () {
this.expireFlash(this.origin)
this.expireContentSettings(this.origin)
}

updateWebview (cb, newSrc) {
Expand Down Expand Up @@ -381,10 +386,10 @@ class Frame extends ImmutableComponent {
this.updateAboutDetails()
}

// For cross-origin navigation, clear temp Flash approvals
// For cross-origin navigation, clear temp approvals
const prevOrigin = siteUtil.getOrigin(prevProps.location)
if (this.origin !== prevOrigin) {
this.expireFlash(prevOrigin)
this.expireContentSettings(prevOrigin)
}

if (this.props.src !== prevProps.src) {
Expand Down
3 changes: 2 additions & 1 deletion js/components/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ class Main extends ImmutableComponent {
}

enableNoScript (settings) {
return siteSettings.activeSettings(settings, this.props.appState, appConfig).noScript
return siteSettings.activeSettings(settings, this.props.appState, appConfig).noScript === true
}

onCloseFrame (activeFrameProps) {
Expand Down Expand Up @@ -1008,6 +1008,7 @@ class Main extends ImmutableComponent {
{
noScriptIsVisible
? <NoScriptInfo frameProps={activeFrame}
noScriptGlobalEnabled={this.props.appState.getIn(['noScript', 'enabled'])}
onHide={this.onHideNoScript} />
: null
}
Expand Down
42 changes: 26 additions & 16 deletions js/components/noScriptInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,41 @@ class NoScriptInfo extends ImmutableComponent {
return siteUtil.getOrigin(this.props.frameProps.get('location'))
}

get isPrivate () {
return this.props.frameProps.get('isPrivate')
}

reload () {
ipc.emit(messages.SHORTCUT_ACTIVE_FRAME_CLEAN_RELOAD)
}

onAllowOnce () {
onAllow (setting) {
if (!this.origin) {
return
}
ipc.send(messages.TEMPORARY_ALLOW_SCRIPTS, this.origin)
appActions.changeSiteSetting(this.origin, 'noScript', setting)
this.reload()
}

onAllow (temp) {
if (!this.origin) {
return
get buttons () {
if (!this.props.noScriptGlobalEnabled) {
// NoScript is not turned on globally
return <div><Button l10nId='allow' className='actionButton'
onClick={this.onAllow.bind(this, false)} /></div>
} else {
return <div>
<Button l10nId='allowScriptsOnce' className='actionButton'
onClick={this.onAllow.bind(this, 0)} />
{this.isPrivate
? null
: <div>
<div><Button l10nId='allowScriptsTemp' className='subtleButton'
onClick={this.onAllow.bind(this, 1)} /></div>
<div><Button l10nId='allow' className='subtleButton'
onClick={this.onAllow.bind(this, false)} /></div>
</div>}
</div>
}
appActions.changeSiteSetting(this.origin, 'noScript', false, temp)
this.reload()
}

render () {
Expand All @@ -50,21 +67,14 @@ class NoScriptInfo extends ImmutableComponent {
<div>
<div className='truncate' data-l10n-args={JSON.stringify(l10nArgs)}
data-l10n-id={this.numberBlocked === 1 ? 'scriptBlocked' : 'scriptsBlocked'} />
<div>
{
// TODO: restore the allow-once button
// TODO: If this is a private tab, this should only allow scripts
// temporarily. Depends on #1824
<Button l10nId='allow' className='actionButton'
onClick={this.onAllow.bind(this, false)} />
}
</div>
{this.buttons}
</div>
</Dialog>
}
}

NoScriptInfo.propTypes = {
noScriptGlobalEnabled: React.PropTypes.bool,
frameProps: React.PropTypes.object,
onHide: React.PropTypes.func
}
Expand Down
2 changes: 0 additions & 2 deletions js/constants/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ const messages = {
HTTPSE_RULE_APPLIED: _, /** @arg {string} name of ruleset file, @arg {Object} details of rewritten request */
// Extensions
NEW_POPUP_WINDOW: _,
// NoScript
TEMPORARY_ALLOW_SCRIPTS: _, /** @arg {string} origin to allow scripts on */
// Localization
LANGUAGE: _, /** @arg {string} langCode, @arg {Array} availableLanguages */
REQUEST_LANGUAGE: _,
Expand Down
5 changes: 2 additions & 3 deletions js/state/contentSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,9 @@ const getContentSettingsFromSiteSettings = (appState) => {
// We do 2 passes for setting content settings. On the first pass we consider all shield types.
for (let hostPattern in hostSettings) {
let hostSetting = hostSettings[hostPattern]
if (typeof hostSetting.noScript === 'boolean') {
// TODO: support temporary override
if (['number', 'boolean'].includes(typeof hostSetting.noScript)) {
addContentSettings(contentSettings.javascript, hostPattern, '*',
hostSetting.noScript ? 'block' : 'allow')
hostSetting.noScript === true ? 'block' : 'allow')
}
if (typeof hostSetting.runInsecureContent === 'boolean') {
addContentSettings(contentSettings.runInsecureContent, hostPattern, '*',
Expand Down

0 comments on commit ec065b9

Please sign in to comment.