@@ -35,6 +35,7 @@ import ResponseOrig from '../src/response.js';
35
35
import Body , { getTotalBytes , extractContentType } from '../src/body.js' ;
36
36
import TestServer from './utils/server.js' ;
37
37
import chaiTimeout from './utils/chai-timeout.js' ;
38
+ import { isDomainOrSubdomain } from '../src/utils/is.js' ;
38
39
39
40
const AbortControllerPolyfill = abortControllerPolyfill . AbortController ;
40
41
const encoder = new TextEncoder ( ) ;
@@ -496,6 +497,66 @@ describe('node-fetch', () => {
496
497
} ) ;
497
498
} ) ;
498
499
500
+ it ( 'should not forward secure headers to 3th party' , async ( ) => {
501
+ const res = await fetch ( `${ base } redirect-to/302/https://httpbin.org/get` , {
502
+ headers : new Headers ( {
503
+ cookie : 'gets=removed' ,
504
+ cookie2 : 'gets=removed' ,
505
+ authorization : 'gets=removed' ,
506
+ 'www-authenticate' : 'gets=removed' ,
507
+ 'other-safe-headers' : 'stays' ,
508
+ 'x-foo' : 'bar'
509
+ } )
510
+ } ) ;
511
+
512
+ const headers = new Headers ( ( await res . json ( ) ) . headers ) ;
513
+ // Safe headers are not removed
514
+ expect ( headers . get ( 'other-safe-headers' ) ) . to . equal ( 'stays' ) ;
515
+ expect ( headers . get ( 'x-foo' ) ) . to . equal ( 'bar' ) ;
516
+ // Unsafe headers should not have been sent to httpbin
517
+ expect ( headers . get ( 'cookie' ) ) . to . equal ( null ) ;
518
+ expect ( headers . get ( 'cookie2' ) ) . to . equal ( null ) ;
519
+ expect ( headers . get ( 'www-authenticate' ) ) . to . equal ( null ) ;
520
+ expect ( headers . get ( 'authorization' ) ) . to . equal ( null ) ;
521
+ } ) ;
522
+
523
+ it ( 'should forward secure headers to same host' , async ( ) => {
524
+ const res = await fetch ( `${ base } redirect-to/302/${ base } inspect` , {
525
+ headers : new Headers ( {
526
+ cookie : 'is=cookie' ,
527
+ cookie2 : 'is=cookie2' ,
528
+ authorization : 'is=authorization' ,
529
+ 'other-safe-headers' : 'stays' ,
530
+ 'www-authenticate' : 'is=www-authenticate' ,
531
+ 'x-foo' : 'bar'
532
+ } )
533
+ } ) ;
534
+
535
+ const headers = new Headers ( ( await res . json ( ) ) . headers ) ;
536
+ // Safe headers are not removed
537
+ expect ( res . url ) . to . equal ( `${ base } inspect` ) ;
538
+ expect ( headers . get ( 'other-safe-headers' ) ) . to . equal ( 'stays' ) ;
539
+ expect ( headers . get ( 'x-foo' ) ) . to . equal ( 'bar' ) ;
540
+ // Unsafe headers should not have been sent to httpbin
541
+ expect ( headers . get ( 'cookie' ) ) . to . equal ( 'is=cookie' ) ;
542
+ expect ( headers . get ( 'cookie2' ) ) . to . equal ( 'is=cookie2' ) ;
543
+ expect ( headers . get ( 'www-authenticate' ) ) . to . equal ( 'is=www-authenticate' ) ;
544
+ expect ( headers . get ( 'authorization' ) ) . to . equal ( 'is=authorization' ) ;
545
+ } ) ;
546
+
547
+ it ( 'isDomainOrSubdomain' , ( ) => {
548
+ // Forwarding headers to same (sub)domain are OK
549
+ expect ( isDomainOrSubdomain ( 'http://a.com' , 'http://a.com' ) ) . to . be . true ;
550
+ expect ( isDomainOrSubdomain ( 'http://a.com' , 'http://www.a.com' ) ) . to . be . true ;
551
+ expect ( isDomainOrSubdomain ( 'http://a.com' , 'http://foo.bar.a.com' ) ) . to . be . true ;
552
+
553
+ // Forwarding headers to parent domain, another sibling or a totally other domain is not ok
554
+ expect ( isDomainOrSubdomain ( 'http://b.com' , 'http://a.com' ) ) . to . be . false ;
555
+ expect ( isDomainOrSubdomain ( 'http://www.a.com' , 'http://a.com' ) ) . to . be . false ;
556
+ expect ( isDomainOrSubdomain ( 'http://bob.uk.com' , 'http://uk.com' ) ) . to . be . false ;
557
+ expect ( isDomainOrSubdomain ( 'http://bob.uk.com' , 'http://xyz.uk.com' ) ) . to . be . false ;
558
+ } ) ;
559
+
499
560
it ( 'should treat broken redirect as ordinary response (follow)' , ( ) => {
500
561
const url = `${ base } redirect/no-location` ;
501
562
return fetch ( url ) . then ( res => {
0 commit comments