@@ -531,6 +531,114 @@ void shouldReportRedirectWithJsLocationMethods(String jsMethod) throws Exception
531
531
assertThat (alertsRaised .get (0 ).getEvidence ().startsWith (HttpHeader .HTTP ), equalTo (true ));
532
532
}
533
533
534
+ private static Stream <Arguments > provideCommentStrings () {
535
+ return Stream .of (
536
+ // Some need to be double escaped because of Java
537
+ Arguments .of ("Block comment" , "/* window.location.replace('@@@content@@@');\n */" ),
538
+ Arguments .of ("Single line" , "// window.location.replace('@@@content@@@');" ),
539
+ Arguments .of (
540
+ "Inline block" ,
541
+ "console.log(\" example\" ); /* console.log(window.location.replace('@@@content@@@')); */" ),
542
+ Arguments .of (
543
+ "Inline incomplete block" ,
544
+ "console.log(\" example\" ); /* console.log(window.location.replace('@@@content@@@')); " ),
545
+ Arguments .of (
546
+ "Inline single line" ,
547
+ "console.log(\" example\" ); // console.log(window.location.replace('@@@content@@@'));" ),
548
+ Arguments .of (
549
+ "Inline single line (w/ unicode escape)" ,
550
+ "console.log(\" 🔥 example\" ); // console.log('\\ u1F525 window.location.replace('@@@content@@@')');" ),
551
+ Arguments .of (
552
+ "Inline single line (w/ malformed (leading) unicode escape)" ,
553
+ "console.log(\" 🔥 example\" ); // console.log('\\ u 1F525 window.location.replace('@@@content@@@')');" ),
554
+ Arguments .of (
555
+ "Inline single line (w/ malformed (mid) unicode escape)" ,
556
+ "console.log(\" 🔥 example\" ); // console.log('\\ u1F 525 window.location.replace('@@@content@@@')');" ),
557
+ Arguments .of (
558
+ "Inline single line (surrogate pair unicode escape)" ,
559
+ "console.log(\" example\" ); // console.log('\\ uD83D\\ uDD25 window.location.replace('@@@content@@@')');" ),
560
+ Arguments .of (
561
+ "Inline single line (malformed surrogate pair unicode escape)" ,
562
+ "console.log(\" example\" ); // console.log('\\ uD83D\\ uD D25 window.location.replace('@@@content@@@')');" ),
563
+ Arguments .of (
564
+ "Inline single line (w/ braced unicode escape)" ,
565
+ "console.log(\" 🔥 example\" ); // console.log('\\ u{1F525} window.location.replace('@@@content@@@')');" ),
566
+ Arguments .of (
567
+ "Inline single line (w/ malformed braced unicode escape)" ,
568
+ "console.log(\" 🔥 example\" ); // console.log('\\ u {1F525} window.location.replace('@@@content@@@')');" ),
569
+ Arguments .of (
570
+ "Inline single line (octal escape)" ,
571
+ "console.log(\" example\" ); // console.log('\\ 141 window.location.replace('@@@content@@@')');" ),
572
+ Arguments .of (
573
+ "Inline single line (malformed octal)" ,
574
+ "console.log(\" example\" ); // console.log('\\ 8 window.location.replace('@@@content@@@')');" ),
575
+ Arguments .of (
576
+ "Inline single line (w/ hex escape)" ,
577
+ "console.log(\" example\" ); // console.log('\\ x41 window.location.replace('@@@content@@@')');" ),
578
+ Arguments .of (
579
+ "Inline single line (w/ malformed (leading) hex escape)" ,
580
+ "console.log(\" example\" ); // console.log('\\ x 41 window.location.replace('@@@content@@@')');" ),
581
+ Arguments .of (
582
+ "Inline single line (w/ malformed (mid) hex escape)" ,
583
+ "console.log(\" example\" ); // console.log('\\ x4 1 window.location.replace('@@@content@@@')');" ),
584
+ Arguments .of (
585
+ "Inline single line (w/ single char escapes)" ,
586
+ "console.log(\" example\" ); // console.log('\\ r\\ n\\ twindow.location.replace('@@@content@@@')');" ),
587
+ Arguments .of (
588
+ "Embedded template expression" ,
589
+ "console.log('value ${1 + 1}'); // comment with window.location.replace('@@@content@@@');" ),
590
+ Arguments .of (
591
+ "Template literal with embedded expression" ,
592
+ "console.log(`value ${1 + 1}`); // comment with window.location.replace('@@@content@@@');" ),
593
+ Arguments .of (
594
+ "Template literal expression containing //" ,
595
+ "console.log(\" value ${ 'not // a comment' }\" ); // real comment window.location.replace('@@@content@@@')" ),
596
+ Arguments .of (
597
+ "Template literal with escaped backtick" ,
598
+ "console.log(\" escaped \\ ` backtick\" ); // trailing comment window.location.replace('@@@content@@@')" ));
599
+ }
600
+
601
+ @ ParameterizedTest (name = "{0}" )
602
+ @ MethodSource ("provideCommentStrings" )
603
+ void shouldNotReportRedirectIfInsideJsComment (String name , String content ) throws Exception {
604
+ // Given
605
+ String test = "/" ;
606
+ String body =
607
+ """
608
+ <!DOCTYPE html>
609
+ <html>
610
+ <head>
611
+ <title>Redirect commented out</title>
612
+ </head>
613
+ <body>
614
+
615
+ <script>function myRedirectFunction()
616
+ %s
617
+ //myRedirectFunction();
618
+ </script>
619
+ """
620
+ .formatted (content );
621
+ nano .addHandler (
622
+ new NanoServerHandler (test ) {
623
+ @ Override
624
+ protected NanoHTTPD .Response serve (NanoHTTPD .IHTTPSession session ) {
625
+ String site = getFirstParamValue (session , "site" );
626
+ if (site != null && !site .isEmpty ()) {
627
+ String withPayload = body .replace (CONTENT_TOKEN , site );
628
+ return newFixedLengthResponse (
629
+ NanoHTTPD .Response .Status .OK , NanoHTTPD .MIME_HTML , withPayload );
630
+ }
631
+ return newFixedLengthResponse ("<html><body></body></html>" );
632
+ }
633
+ });
634
+ HttpMessage msg = getHttpMessage (test + "?site=xxx" );
635
+ rule .init (msg , parent );
636
+ // When
637
+ rule .scan ();
638
+ // Then
639
+ assertThat (alertsRaised .size (), equalTo (0 ));
640
+ }
641
+
534
642
private static Stream <Arguments > createJsMethodBooleanPairs () {
535
643
return Stream .of (
536
644
Arguments .of ("location.reload" , true ),
0 commit comments