@@ -27,6 +27,7 @@ describe('middlewares', () => {
2727 expect ( fakeReq . headers [ 'content-type' ] ) . toEqual ( undefined ) ;
2828 const contentType = 'image/jpeg' ;
2929 fakeReq . body . _ContentType = contentType ;
30+ fakeReq . ip = '127.0.0.1' ;
3031 middlewares . handleParseHeaders ( fakeReq , fakeRes , ( ) => {
3132 expect ( fakeReq . headers [ 'content-type' ] ) . toEqual ( contentType ) ;
3233 expect ( fakeReq . body . _ContentType ) . toEqual ( undefined ) ;
@@ -151,7 +152,92 @@ describe('middlewares', () => {
151152 ) ;
152153 } ) ;
153154
154- it ( 'should not succeed if the ip does not belong to masterKeyIps list' , async ( ) => {
155+ it ( 'should match address' , ( ) => {
156+ const ipv6 = '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ;
157+ const anotherIpv6 = '::ffff:101.10.0.1' ;
158+ const ipv4 = '192.168.0.101' ;
159+ const localhostV6 = '::1' ;
160+ const localhostV62 = '::ffff:127.0.0.1' ;
161+ const localhostV4 = '127.0.0.1' ;
162+
163+ const v6 = [ ipv6 , anotherIpv6 ] ;
164+ v6 . forEach ( ip => {
165+ expect ( middlewares . checkIpRanges ( ip , [ '::/0' ] ) ) . toBe ( true ) ;
166+ expect ( middlewares . checkIpRanges ( ip , [ '::' ] ) ) . toBe ( true ) ;
167+ expect ( middlewares . checkIpRanges ( ip , [ '0.0.0.0' ] ) ) . toBe ( false ) ;
168+ expect ( middlewares . checkIpRanges ( ip , [ '123.123.123.123' ] ) ) . toBe ( false ) ;
169+ } ) ;
170+
171+ expect ( middlewares . checkIpRanges ( ipv6 , [ anotherIpv6 ] ) ) . toBe ( false ) ;
172+ expect ( middlewares . checkIpRanges ( ipv6 , [ ipv6 ] ) ) . toBe ( true ) ;
173+ expect ( middlewares . checkIpRanges ( ipv6 , [ '2001:db8:85a3:0:0:8a2e:0:0/100' ] ) ) . toBe ( true ) ;
174+
175+ expect ( middlewares . checkIpRanges ( ipv4 , [ '::' ] ) ) . toBe ( false ) ;
176+ expect ( middlewares . checkIpRanges ( ipv4 , [ '::/0' ] ) ) . toBe ( true ) ;
177+ expect ( middlewares . checkIpRanges ( ipv4 , [ '0.0.0.0' ] ) ) . toBe ( true ) ;
178+ expect ( middlewares . checkIpRanges ( ipv4 , [ '123.123.123.123' ] ) ) . toBe ( false ) ;
179+ expect ( middlewares . checkIpRanges ( ipv4 , [ ipv4 ] ) ) . toBe ( true ) ;
180+ expect ( middlewares . checkIpRanges ( ipv4 , [ '192.168.0.0/24' ] ) ) . toBe ( true ) ;
181+
182+ expect ( middlewares . checkIpRanges ( localhostV4 , [ '::1' ] ) ) . toBe ( false ) ;
183+ expect ( middlewares . checkIpRanges ( localhostV6 , [ '::1' ] ) ) . toBe ( true ) ;
184+ // ::ffff:127.0.0.1 is a padded ipv4 address but not ::1
185+ expect ( middlewares . checkIpRanges ( localhostV62 , [ '::1' ] ) ) . toBe ( false ) ;
186+ // ::ffff:127.0.0.1 is a padded ipv4 address and is a match for 127.0.0.1
187+ expect ( middlewares . checkIpRanges ( localhostV62 , [ '127.0.0.1' ] ) ) . toBe ( true ) ;
188+ } ) ;
189+
190+ it ( 'can allow all with masterKeyIPs' , async ( ) => {
191+ const combinations = [
192+ {
193+ masterKeyIps : [ '::/0' ] ,
194+ ips : [ '::ffff:192.168.0.101' , '192.168.0.101' ] ,
195+ id : 'allowAllIpV6' ,
196+ } ,
197+ {
198+ masterKeyIps : [ '0.0.0.0' ] ,
199+ ips : [ '192.168.0.101' ] ,
200+ id : 'allowAllIpV4' ,
201+ } ,
202+ ] ;
203+ for ( const combination of combinations ) {
204+ AppCache . put ( combination . id , {
205+ masterKey : 'masterKey' ,
206+ masterKeyIps : combination . masterKeyIps ,
207+ } ) ;
208+ await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ;
209+ for ( const ip of combination . ips ) {
210+ fakeReq = {
211+ originalUrl : 'http://example.com/parse/' ,
212+ url : 'http://example.com/' ,
213+ body : {
214+ _ApplicationId : combination . id ,
215+ } ,
216+ headers : { } ,
217+ get : key => {
218+ return fakeReq . headers [ key . toLowerCase ( ) ] ;
219+ } ,
220+ } ;
221+ fakeReq . ip = ip ;
222+ fakeReq . headers [ 'x-parse-master-key' ] = 'masterKey' ;
223+ await new Promise ( resolve => middlewares . handleParseHeaders ( fakeReq , fakeRes , resolve ) ) ;
224+ expect ( fakeReq . auth . isMaster ) . toBe ( true ) ;
225+ }
226+ }
227+ } ) ;
228+
229+ it ( 'can allow localhost with masterKeyIPs' , async ( ) => {
230+ AppCache . put ( fakeReq . body . _ApplicationId , {
231+ masterKey : 'masterKey' ,
232+ masterKeyIps : [ '::' ] ,
233+ } ) ;
234+ fakeReq . ip = '::ffff:127.0.0.1' ;
235+ fakeReq . headers [ 'x-parse-master-key' ] = 'masterKey' ;
236+ await new Promise ( resolve => middlewares . handleParseHeaders ( fakeReq , fakeRes , resolve ) ) ;
237+ expect ( fakeReq . auth . isMaster ) . toBe ( true ) ;
238+ } ) ;
239+
240+ it ( 'should not succeed if the ip does not belong to masterKeyIps list (ipv4)' , async ( ) => {
155241 AppCache . put ( fakeReq . body . _ApplicationId , {
156242 masterKey : 'masterKey' ,
157243 masterKeyIps : [ '10.0.0.1' ] ,
@@ -162,6 +248,17 @@ describe('middlewares', () => {
162248 expect ( fakeReq . auth . isMaster ) . toBe ( false ) ;
163249 } ) ;
164250
251+ it ( 'should not succeed if the ip does not belong to masterKeyIps list (ipv6)' , async ( ) => {
252+ AppCache . put ( fakeReq . body . _ApplicationId , {
253+ masterKey : 'masterKey' ,
254+ masterKeyIps : [ '::1' ] ,
255+ } ) ;
256+ fakeReq . ip = '::ffff:101.10.0.1' ;
257+ fakeReq . headers [ 'x-parse-master-key' ] = 'masterKey' ;
258+ await new Promise ( resolve => middlewares . handleParseHeaders ( fakeReq , fakeRes , resolve ) ) ;
259+ expect ( fakeReq . auth . isMaster ) . toBe ( false ) ;
260+ } ) ;
261+
165262 it ( 'should not succeed if the ip does not belong to maintenanceKeyIps list' , async ( ) => {
166263 const logger = require ( '../lib/logger' ) . logger ;
167264 spyOn ( logger , 'error' ) . and . callFake ( ( ) => { } ) ;
0 commit comments