@@ -531,6 +531,114 @@ void shouldReportRedirectWithJsLocationMethods(String jsMethod) throws Exception
531531 assertThat (alertsRaised .get (0 ).getEvidence ().startsWith (HttpHeader .HTTP ), equalTo (true ));
532532 }
533533
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+
534642 private static Stream <Arguments > createJsMethodBooleanPairs () {
535643 return Stream .of (
536644 Arguments .of ("location.reload" , true ),
0 commit comments