@@ -366,16 +366,17 @@ var RequestGuard = (() => {
366366 return ALLOW ;
367367 } ,
368368 onHeadersReceived ( request ) {
369- normalizeRequest ( request ) ;
370- let result = ALLOW ;
371- let promises = [ ] ;
372369 // called for main_frame, sub_frame and object
370+
373371 // check for duplicate calls
374- let headersModified = false ;
375372 let pending = pendingRequests . get ( request . requestId ) ;
376373 if ( pending ) {
377374 if ( pending . headersProcessed ) {
378- debug ( "[WARNING] already processed " , request ) ;
375+ if ( ! request . fromCache ) {
376+ debug ( "Headers already processed, skipping " , request ) ;
377+ return ALLOW ;
378+ }
379+ debug ( "Reprocessing headers for cached request " , request ) ;
379380 } else {
380381 debug ( "onHeadersReceived" , request ) ;
381382 }
@@ -384,6 +385,28 @@ var RequestGuard = (() => {
384385 initPendingRequest ( request ) ;
385386 pending = pendingRequests . get ( request . requestId ) ;
386387 }
388+ if ( request . fromCache && listeners . onHeadersReceived . resetCSP && ! pending . resetCachedCSP ) {
389+ debug ( "Resetting CSP Headers" ) ;
390+ pending . resetCachedCSP = true ;
391+ let { responseHeaders} = request ;
392+ let headersCount = responseHeaders . length ;
393+ let purged = false ;
394+ responseHeaders . forEach ( ( h , index ) => {
395+ if ( csp . isMine ( h ) ) {
396+ responseHeaders . splice ( index , 1 ) ;
397+ }
398+ } ) ;
399+ if ( headersCount > responseHeaders . length ) {
400+ debug ( "Resetting cached NoScript CSP header(s)" , request ) ;
401+ return { responseHeaders} ;
402+ }
403+ }
404+
405+ normalizeRequest ( request ) ;
406+ let result = ALLOW ;
407+ let promises = [ ] ;
408+ let headersModified = false ;
409+
387410 pending . headersProcessed = true ;
388411 let { url, documentUrl, tabId, responseHeaders, type} = request ;
389412 let isMainFrame = type === "main_frame" ;
@@ -414,6 +437,7 @@ var RequestGuard = (() => {
414437 }
415438 if ( headersModified ) {
416439 result = { responseHeaders} ;
440+ debug ( "Headers changed " , request ) ;
417441 }
418442 } catch ( e ) {
419443 error ( e , "Error in onHeadersReceived" , request ) ;
@@ -440,7 +464,7 @@ var RequestGuard = (() => {
440464 if ( pending ) {
441465 pending . scriptBlocked = scriptBlocked ;
442466 if ( ! ( pending . headersProcessed &&
443- ( scriptBlocked || ! ns . requestCan ( request , "script" ) )
467+ ( scriptBlocked || ns . requestCan ( request , "script" ) )
444468 ) ) {
445469 debug ( "[WARNING] onHeadersReceived %s %o" , frameId , tabId ,
446470 pending . headersProcessed ? "has been overridden on" : "could not process" ,
@@ -508,29 +532,36 @@ var RequestGuard = (() => {
508532 let filterDocs = { urls : allUrls , types : docTypes } ;
509533 let filterAll = { urls : allUrls } ;
510534 listen ( "onBeforeRequest" , filterAll , [ "blocking" ] ) ;
535+
536+ const mergingCSP = parseInt ( navigator . userAgent . replace ( / .* F i r e f o x \/ ( \d + ) .* / , "$1" ) ) >= 77 ;
537+ if ( mergingCSP ) {
538+ // In Gecko>=77 (https://bugzilla.mozilla.org/show_bug.cgi?id=1462989)
539+ // we need to cleanup our own cached headers in a dedicated listener :(
540+ // see also https://trac.torproject.org/projects/tor/ticket/34305
541+ wr . onHeadersReceived . addListener (
542+ listeners . onHeadersReceived . resetCSP = request => {
543+ return listeners . onHeadersReceived ( request ) ;
544+ } , filterDocs , [ "blocking" , "responseHeaders" ] ) ;
545+ }
511546 listen ( "onHeadersReceived" , filterDocs , [ "blocking" , "responseHeaders" ] ) ;
512- ( listeners . onHeadersReceivedLast = new LastListener ( wr . onHeadersReceived , request => {
547+ // Still, other extensions extensions may accidentally delete our CSP
548+ // if called before us, hence we try our best reinjecting in the end
549+ ( listeners . onHeadersReceivedLast =
550+ new LastListener ( wr . onHeadersReceived , request => {
513551 let { requestId, responseHeaders} = request ;
514552 let pending = pendingRequests . get ( request . requestId ) ;
515553 if ( pending && pending . headersProcessed ) {
516554 let { cspHeader} = pending ;
517555 if ( cspHeader ) {
518- debug ( "Safety net: injecting again %o in %o" , cspHeader , request ) ;
519- for ( let h of responseHeaders ) {
520- if ( h . name === cspHeader . name ) {
521- h . value = cspHeader . value ;
522- cspHeader = null ;
523- break ;
524- }
525- }
526- if ( cspHeader ) responseHeaders . push ( cspHeader ) ;
556+ responseHeaders . push ( cspHeader ) ;
527557 return { responseHeaders} ;
528558 }
529559 } else {
530560 debug ( "[WARNING] onHeadersReceived not called (yet?)" , request ) ;
531561 }
532- return null ;
562+ return ALLOW ;
533563 } , filterDocs , [ "blocking" , "responseHeaders" ] ) ) . install ( ) ;
564+
534565 listen ( "onResponseStarted" , filterDocs , [ "responseHeaders" ] ) ;
535566 listen ( "onCompleted" , filterAll ) ;
536567 listen ( "onErrorOccurred" , filterAll ) ;
@@ -548,6 +579,9 @@ var RequestGuard = (() => {
548579 }
549580 }
550581 wr . onBeforeRequest . removeListener ( onViolationReport ) ;
582+ if ( listeners . onHeadersReceived . resetCSP ) {
583+ wr . onHeadersReceived . removeListener ( listeners . onHeadersReceived . resetCSP ) ;
584+ }
551585 Messages . removeHandler ( messageHandler ) ;
552586 }
553587 } ;
0 commit comments