@@ -103,48 +103,70 @@ var TabGuard = (() => {
103103
104104 // we suspect tabs which 1) have not been removed/discarded, 2) are restricted by policy, 3) can run JavaScript
105105 let suspiciousTabs = [ ...ties ] . map ( TabCache . get ) . filter (
106- tab => tab && ! tab . discarded && ns . isEnforced ( tab . tabId ) &&
107- ( tab . url === "about:blank" || ns . policy . can ( tab . url , "script" ) ) // TODO: replace about:blank with actual document.domain / window.opener by injecting a content script
106+ tab => tab && ! tab . discarded && ns . isEnforced ( tab . id ) &&
107+ ( ! ( tab . _isExplicitOrigin = tab . _isExplicitOrigin || / ^ (?: h t t p s ? | f t p s ? | f i l e ) : / . test ( tab . url ) ) || ns . policy . can ( tab . url , "script" ) )
108108 ) ;
109109
110- let legitDomains = allowedGroups [ tabDomain ] || new Set ( [ tabDomain ] ) ;
111-
112- let otherDomains = new Set ( suspiciousTabs . map ( tab => getDomain ( tab . url ) ) . filter ( d => d && ! legitDomains . has ( d ) ) ) ;
113- if ( otherDomains . size === 0 ) return ; // no cross-site ties, no party
114-
115- if ( ! requestHeaders . some ( h => AUTH_HEADERS_RX . test ( h . name ) ) ) return ; // no auth, no party
116-
117- // danger zone
118-
119- let filterAuth = ( ) => {
120- requestHeaders = requestHeaders . filter ( h => ! AUTH_HEADERS_RX . test ( h . name ) ) ;
121- debug ( "[TabGuard] Removing auth headers from %o (%o)" , request , requestHeaders ) ;
122- return { requestHeaders} ;
123- } ;
124-
125- let quietDomains = filteredGroups [ tabDomain ] ;
126- if ( mainFrame ) {
127- let mustPrompt = ( ! quietDomains || [ ...otherDomains ] . some ( d => ! quietDomains . has ( d ) ) ) ;
128- if ( mustPrompt ) {
129- return ( async ( ) => {
130- let options = [
131- { label : _ ( "TabGuard_optAnonymize" ) , checked : true } ,
132- { label : _ ( "TabGuard_optAllow" ) } ,
133- ] ;
134- let ret = await Prompts . prompt ( {
135- title : _ ( "TabGuard_title" ) ,
136- message : _ ( "TabGuard_message" , [ tabDomain , [ ...otherDomains ] . join ( ", " ) ] ) ,
137- options} ) ;
138- if ( ret . button !== 0 ) return { cancel : true } ;
139- let list = ret . option === 0 ? filteredGroups : allowedGroups ;
140- otherDomains . add ( tabDomain ) ;
141- for ( let d of otherDomains ) list [ d ] = otherDomains ;
142- return list === filteredGroups ? filterAuth ( ) : null ;
143- } ) ( ) ;
110+ return suspiciousTabs . length > 0 && ( async ( ) => {
111+
112+ let suspiciousDomains = [ ] ;
113+ await Promise . all ( suspiciousTabs . map ( async ( tab ) => {
114+ if ( ! tab . _isExplicitOrigin ) { // e.g. about:blank
115+ // let's try retrieving actual origin
116+ tab . _externalUrl = tab . url ;
117+ tab . _isExplicitOrigin = true ;
118+ try {
119+ tab . url = await browser . tabs . executeScript ( tab . id , {
120+ runAt : "document_start" ,
121+ code : "window.origin === 'null' ? window.location.href : window.origin"
122+ } ) ;
123+ } catch ( e ) {
124+ debug ( e ) ;
125+ }
126+ debug ( `Real origin for ${ tab . _externalUrl } (tab ${ tab . id } ) is ${ tab . url } .` ) ;
127+ if ( ! ns . policy . can ( tab . url , "script" ) ) return ;
128+ }
129+ suspiciousDomains . push ( getDomain ( tab . url ) ) ;
130+ } ) ) ;
131+
132+ let legitDomains = allowedGroups [ tabDomain ] || new Set ( [ tabDomain ] ) ;
133+ let otherDomains = new Set ( suspiciousDomains . filter ( d => d && ! legitDomains . has ( d ) ) ) ;
134+ if ( otherDomains . size === 0 ) return ; // no cross-site ties, no party
135+
136+ if ( ! requestHeaders . some ( h => AUTH_HEADERS_RX . test ( h . name ) ) ) return ; // no auth, no party
137+
138+ // danger zone
139+
140+ let filterAuth = ( ) => {
141+ requestHeaders = requestHeaders . filter ( h => ! AUTH_HEADERS_RX . test ( h . name ) ) ;
142+ debug ( "[TabGuard] Removing auth headers from %o (%o)" , request , requestHeaders ) ;
143+ return { requestHeaders} ;
144+ } ;
145+
146+ let quietDomains = filteredGroups [ tabDomain ] ;
147+ if ( mainFrame ) {
148+ let mustPrompt = ( ! quietDomains || [ ...otherDomains ] . some ( d => ! quietDomains . has ( d ) ) ) ;
149+ if ( mustPrompt ) {
150+ return ( async ( ) => {
151+ let options = [
152+ { label : _ ( "TabGuard_optAnonymize" ) , checked : true } ,
153+ { label : _ ( "TabGuard_optAllow" ) } ,
154+ ] ;
155+ let ret = await Prompts . prompt ( {
156+ title : _ ( "TabGuard_title" ) ,
157+ message : _ ( "TabGuard_message" , [ tabDomain , [ ...otherDomains ] . join ( ", " ) ] ) ,
158+ options} ) ;
159+ if ( ret . button !== 0 ) return { cancel : true } ;
160+ let list = ret . option === 0 ? filteredGroups : allowedGroups ;
161+ otherDomains . add ( tabDomain ) ;
162+ for ( let d of otherDomains ) list [ d ] = otherDomains ;
163+ return list === filteredGroups ? filterAuth ( ) : null ;
164+ } ) ( ) ;
165+ }
144166 }
145- }
146- let mustFilter = mainFrame || quietDomains && [ ... otherDomains ] . some ( d => quietDomains . has ( d ) )
147- return mustFilter ? filterAuth ( ) : null ;
167+ let mustFilter = mainFrame || quietDomains && [ ... otherDomains ] . some ( d => quietDomains . has ( d ) )
168+ return mustFilter ? filterAuth ( ) : null ;
169+ } ) ( ) ;
148170 } ,
149171 postCheck ( request ) {
150172 let { requestId, tabId} = request ;
0 commit comments