@@ -10,6 +10,38 @@ const ORG2 = { id: 2 };
10
10
11
11
const TestOctokit = Octokit . plugin ( paginateRest , restEndpointMethods ) ;
12
12
describe ( "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
+
13
45
it ( ".paginate()" , async ( ) => {
14
46
const mock = fetchMock
15
47
. createInstance ( )
0 commit comments