@@ -35,6 +35,7 @@ import ResponseOrig from '../src/response.js';
3535import Body , { getTotalBytes , extractContentType } from '../src/body.js' ;
3636import TestServer from './utils/server.js' ;
3737import chaiTimeout from './utils/chai-timeout.js' ;
38+ import { isDomainOrSubdomain } from '../src/utils/is.js' ;
3839
3940const AbortControllerPolyfill = abortControllerPolyfill . AbortController ;
4041const encoder = new TextEncoder ( ) ;
@@ -496,6 +497,66 @@ describe('node-fetch', () => {
496497 } ) ;
497498 } ) ;
498499
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+
499560 it ( 'should treat broken redirect as ordinary response (follow)' , ( ) => {
500561 const url = `${ base } redirect/no-location` ;
501562 return fetch ( url ) . then ( res => {
0 commit comments