@@ -5,12 +5,13 @@ const { assert } = require('chai')
5
5
const path = require ( 'path' )
6
6
const zlib = require ( 'zlib' )
7
7
const fs = require ( 'node:fs' )
8
+ const semver = require ( 'semver' )
8
9
const agent = require ( '../plugins/agent' )
9
10
const appsec = require ( '../../src/appsec' )
10
11
const Config = require ( '../../src/config' )
11
12
const { json } = require ( '../../src/appsec/blocked_templates' )
12
13
13
- withVersions ( 'fastify' , 'fastify' , '>=2' , version => {
14
+ withVersions ( 'fastify' , 'fastify' , '>=2' , ( fastifyVersion , _ , fastifyLoadedVersion ) => {
14
15
describe ( 'Suspicious request blocking - query' , ( ) => {
15
16
let server , requestBody , axios
16
17
@@ -19,7 +20,7 @@ withVersions('fastify', 'fastify', '>=2', version => {
19
20
} )
20
21
21
22
before ( ( done ) => {
22
- const fastify = require ( `../../../../versions/fastify@${ version } ` ) . get ( )
23
+ const fastify = require ( `../../../../versions/fastify@${ fastifyVersion } ` ) . get ( )
23
24
24
25
const app = fastify ( )
25
26
@@ -84,7 +85,7 @@ withVersions('fastify', 'fastify', '>=2', version => {
84
85
} )
85
86
86
87
before ( ( done ) => {
87
- const fastify = require ( `../../../../versions/fastify@${ version } ` ) . get ( )
88
+ const fastify = require ( `../../../../versions/fastify@${ fastifyVersion } ` ) . get ( )
88
89
89
90
const app = fastify ( )
90
91
@@ -184,7 +185,7 @@ withVersions('fastify', 'fastify', '>=2', version => {
184
185
} )
185
186
186
187
before ( ( done ) => {
187
- const fastify = require ( `../../../../versions/fastify@${ version } ` ) . get ( )
188
+ const fastify = require ( `../../../../versions/fastify@${ fastifyVersion } ` ) . get ( )
188
189
189
190
const app = fastify ( )
190
191
@@ -259,7 +260,7 @@ withVersions('fastify', 'fastify', '>=2', version => {
259
260
} )
260
261
261
262
before ( ( done ) => {
262
- const fastify = require ( `../../../../versions/fastify@${ version } ` ) . get ( )
263
+ const fastify = require ( `../../../../versions/fastify@${ fastifyVersion } ` ) . get ( )
263
264
264
265
const app = fastify ( )
265
266
app . get ( '/multiple-path-params/:parameter1/:parameter2' , ( request , reply ) => {
@@ -441,21 +442,21 @@ withVersions('fastify', 'fastify', '>=2', version => {
441
442
let server , requestCookie , axios
442
443
443
444
before ( function ( ) {
444
- if ( version === '3.9.2' ) {
445
+ if ( semver . intersects ( fastifyLoadedVersion , '3.9.2' ) ) {
445
446
// Fastify 3.9.2 is incompatible with @fastify/cookie >=6
446
447
this . skip ( )
447
448
}
448
449
449
450
// Skip preParsing hook for Fastify 2.x - has compatibility issues
450
- if ( hook === 'preParsing' && version . startsWith ( '2' ) ) {
451
+ if ( hook === 'preParsing' && semver . intersects ( fastifyLoadedVersion , '2' ) ) {
451
452
this . skip ( )
452
453
}
453
454
454
455
return agent . load ( [ 'fastify' , '@fastify/cookie' , 'http' ] , { client : false } )
455
456
} )
456
457
457
458
before ( ( done ) => {
458
- const fastify = require ( `../../../../versions/fastify@${ version } ` ) . get ( )
459
+ const fastify = require ( `../../../../versions/fastify@${ fastifyVersion } ` ) . get ( )
459
460
const fastifyCookie = require ( `../../../../versions/@fastify/cookie@${ cookieVersion } ` ) . get ( )
460
461
461
462
const app = fastify ( )
@@ -498,9 +499,7 @@ withVersions('fastify', 'fastify', '>=2', version => {
498
499
} )
499
500
500
501
after ( ( ) => {
501
- if ( server ) {
502
- server . close ( )
503
- }
502
+ server ?. close ( )
504
503
return agent . close ( { ritmReset : false } )
505
504
} )
506
505
@@ -530,6 +529,98 @@ withVersions('fastify', 'fastify', '>=2', version => {
530
529
} )
531
530
} )
532
531
} )
532
+
533
+ describe ( 'Suspicious request blocking - multipart' , ( ) => {
534
+ withVersions ( 'fastify' , '@fastify/multipart' , ( multipartVersion , _ , multipartLoadedVersion ) => {
535
+ let server , uploadSpy , axios
536
+
537
+ // The skips in this section are complex because of the incompatibilities between Fastify and @fastify /multipart
538
+ // We are not testing every major version of those libraries because of the complexity of the tests
539
+ before ( function ( ) {
540
+ // @fastify /multipart is not compatible with Fastify 2.x
541
+ if ( semver . intersects ( fastifyLoadedVersion , '2' ) ) {
542
+ this . skip ( )
543
+ }
544
+
545
+ // This Fastify version is working only with @fastify /multipart 6
546
+ if ( semver . intersects ( fastifyLoadedVersion , '3.9.2' ) && semver . intersects ( multipartLoadedVersion , '>=7' ) ) {
547
+ this . skip ( )
548
+ }
549
+
550
+ // Fastify 5 drop le support pour multipart <7
551
+ if ( semver . intersects ( fastifyLoadedVersion , '>=5' ) && semver . intersects ( multipartLoadedVersion , '<7.0.0' ) ) {
552
+ this . skip ( )
553
+ }
554
+
555
+ return agent . load ( [ 'fastify' , '@fastify/multipart' , 'http' ] , { client : false } )
556
+ } )
557
+
558
+ before ( ( done ) => {
559
+ const fastify = require ( `../../../../versions/fastify@${ fastifyVersion } ` ) . get ( )
560
+ const fastifyMultipart = require ( `../../../../versions/@fastify/multipart@${ multipartVersion } ` ) . get ( )
561
+
562
+ const app = fastify ( )
563
+
564
+ app . register ( fastifyMultipart , { attachFieldsToBody : true } )
565
+
566
+ app . post ( '/' , ( request , reply ) => {
567
+ uploadSpy ( )
568
+ reply . send ( 'DONE' )
569
+ } )
570
+
571
+ app . listen ( { port : 0 } , ( ) => {
572
+ const port = server . address ( ) . port
573
+ axios = Axios . create ( { baseURL : `http://localhost:${ port } ` } )
574
+ done ( )
575
+ } )
576
+ server = app . server
577
+ } )
578
+
579
+ beforeEach ( ( ) => {
580
+ uploadSpy = sinon . stub ( )
581
+ appsec . enable ( new Config ( {
582
+ appsec : {
583
+ enabled : true ,
584
+ rules : path . join ( __dirname , 'body-parser-rules.json' )
585
+ }
586
+ } ) )
587
+ } )
588
+
589
+ afterEach ( ( ) => {
590
+ appsec . disable ( )
591
+ } )
592
+
593
+ after ( ( ) => {
594
+ server ?. close ( )
595
+ return agent . close ( { ritmReset : false } )
596
+ } )
597
+
598
+ it ( 'should not block the request without an attack' , async ( ) => {
599
+ const form = new FormData ( )
600
+ form . append ( 'key' , 'value' )
601
+
602
+ const res = await axios . post ( '/' , form )
603
+
604
+ assert . strictEqual ( res . status , 200 )
605
+ sinon . assert . calledOnce ( uploadSpy )
606
+ assert . strictEqual ( res . data , 'DONE' )
607
+ } )
608
+
609
+ it ( 'should block the request when attack is detected' , async ( ) => {
610
+ try {
611
+ const form = new FormData ( )
612
+ form . append ( 'key' , 'testattack' )
613
+
614
+ await axios . post ( '/' , form )
615
+
616
+ return Promise . reject ( new Error ( 'Request should not return 200' ) )
617
+ } catch ( e ) {
618
+ assert . strictEqual ( e . response . status , 403 )
619
+ sinon . assert . notCalled ( uploadSpy )
620
+ }
621
+ } )
622
+ } )
623
+ } )
533
624
} )
534
625
535
626
describe ( 'Api Security - Fastify' , ( ) => {
0 commit comments