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