@@ -10,6 +10,38 @@ const ORG2 = { id: 2 };
1010
1111const TestOctokit = Octokit . plugin ( paginateRest , restEndpointMethods ) ;
1212describe ( "pagination" , ( ) => {
13+ it ( "Test ReDoS - attack string" , async ( ) => {
14+ const ReDosOctokit = Octokit . plugin ( paginateRest ) ;
15+ const octokit = new ReDosOctokit ( {
16+ auth : "your-github-token" ,
17+ } ) ;
18+ octokit . hook . wrap ( "request" , async ( request , options ) => {
19+ const maliciousLinkHeader = "" + "<" . repeat ( 100000 ) + ">" ;
20+ return {
21+ data : [ ] ,
22+ headers : {
23+ link : maliciousLinkHeader ,
24+ } ,
25+ } ;
26+ } ) ;
27+ const startTime = performance . now ( ) ;
28+ try {
29+ for await ( const normalizedResponse of octokit . paginate . iterator (
30+ "GET /repos/{owner}/{repo}/issues" , { owner : "DayShift" , repo : "ReDos" , per_page : 100 }
31+ ) ) { }
32+ } catch ( error ) {
33+ // pass
34+ }
35+ const endTime = performance . now ( ) ;
36+ const elapsedTime = endTime - startTime ;
37+ const reDosThreshold = 2000 ;
38+
39+ expect ( elapsedTime ) . toBeLessThanOrEqual ( reDosThreshold ) ;
40+ if ( elapsedTime > reDosThreshold ) {
41+ console . warn ( `🚨 Potential ReDoS Attack! getDuration method took ${ elapsedTime . toFixed ( 2 ) } ms, exceeding threshold of ${ reDosThreshold } ms.` ) ;
42+ }
43+ } ) ;
44+
1345 it ( ".paginate()" , async ( ) => {
1446 const mock = fetchMock
1547 . createInstance ( )
0 commit comments