5757import org .owasp .benchmarkutils .entities .TestCaseSetupException ;
5858import org .owasp .benchmarkutils .entities .TestSuite ;
5959import org .owasp .benchmarkutils .entities .VerifyFixOutput ;
60+ import org .owasp .benchmarkutils .entities .VerifyFixesOutput ;
6061import org .owasp .benchmarkutils .helpers .Utils ;
6162import org .xml .sax .SAXException ;
6263
@@ -116,9 +117,16 @@ public class BenchmarkCrawlerVerification extends BenchmarkCrawler {
116117 private Map <String , TestCaseVerificationResults > testCaseNameToTestCaseVerificationResultsMap =
117118 new HashMap <>();
118119
119- private List <VerifyFixOutput > exploitedFixedTestcases = new ArrayList <>();
120- private List <VerifyFixOutput > brokenFixedTestcases = new ArrayList <>();
121- private List <VerifyFixOutput > notVerifiableFixedTestcases = new ArrayList <>();
120+ private List <VerifyFixOutput > vulnerableTestcases = new ArrayList <>();
121+ private List <VerifyFixOutput > notVulnerableTestcases = new ArrayList <>();
122+ private List <VerifyFixOutput > notVerifiableModifiedVulnerableTestcases = new ArrayList <>();
123+ private List <VerifyFixOutput > exploitedModifiedVulnerableTestcases = new ArrayList <>();
124+ private List <VerifyFixOutput > brokenModifiedVulnerableTestcases = new ArrayList <>();
125+ private List <VerifyFixOutput > notVerifiableModifiedNotVulnerableTestcases = new ArrayList <>();
126+ private List <VerifyFixOutput > exploitedModifiedNotVulnerableTestcases = new ArrayList <>();
127+ private List <VerifyFixOutput > brokenModifiedNotVulnerableTestcases = new ArrayList <>();
128+
129+ private List <VerifyFixOutput > verifyFixesOutputList = new ArrayList <>();
122130
123131 BenchmarkCrawlerVerification () {
124132 // A default constructor required to support Maven plugin API.
@@ -394,10 +402,30 @@ protected void crawl(TestSuite testSuite) throws Exception {
394402 FILE_UNVERIFIABLE_LOG );
395403 }
396404
405+ VerifyFixesOutput verifyFixesOutput = new VerifyFixesOutput ();
406+ verifyFixesOutput .setList (verifyFixesOutputList );
407+
408+ File verifyFixResultFile = new File (getOutputDirectory (), FILENAME_VERIFY_FIX_RESULT );
409+ try (BufferedWriter writer = new BufferedWriter (new FileWriter (verifyFixResultFile ))) {
410+ String output = Utils .objectToJson (verifyFixesOutput );
411+ // System.out.println(output);
412+ writer .write (output );
413+ } catch (IOException e ) {
414+ System .out .println (
415+ "ERROR: Could not write VerifyFixOutputList to file "
416+ + verifyFixResultFile );
417+ e .printStackTrace ();
418+ } catch (JAXBException e ) {
419+ System .out .println ("ERROR: Could not marshall VerifyFixOutputList to JSON" );
420+ e .printStackTrace ();
421+ }
422+
397423 System .out .printf ("Test case time measurements written to: %s%n" , FILE_TIMES_LOG );
398424
399425 RegressionTesting .printCrawlSummary (results );
400- printFixVerificationSummary ();
426+ if (Boolean .parseBoolean (verifyFixed )) {
427+ printFixVerificationSummary ();
428+ }
401429 System .out .println ();
402430 System .out .println (completionMessage );
403431 }
@@ -406,13 +434,51 @@ protected void crawl(TestSuite testSuite) throws Exception {
406434 // cleanupSetups(setups);
407435 }
408436
437+ private boolean isTestCaseModified (
438+ String unfixedSourceDirectory , String fixedSourceDirectory , String testCaseName )
439+ throws IOException {
440+ // FIXME: Generalize this so it can support languages other than Java and multiple
441+ // source files per testcase.
442+ String unfixedSourceFile =
443+ Paths .get (unfixedSourceDirectory , testCaseName ).toString () + ".java" ;
444+ String fixedSourceFile = Paths .get (fixedSourceDirectory , testCaseName ).toString () + ".java" ;
445+ String unfixedSourceFileContents =
446+ new String (Files .readAllBytes (Paths .get (unfixedSourceFile )));
447+ String fixedSourceFileContents = new String (Files .readAllBytes (Paths .get (fixedSourceFile )));
448+
449+ // Skip testcase in verifyFixed mode if fixed source code is unchanged.
450+ return !unfixedSourceFileContents .equals (fixedSourceFileContents );
451+ }
452+
409453 private void printFixVerificationSummary () {
410- System .out .println ("Fix verification summary:" );
411454 System .out .println ();
412- System .out .println ("\t Exploited fixed test cases:\t " + exploitedFixedTestcases .size ());
413- System .out .println ("\t Broken fixed test cases:\t " + brokenFixedTestcases .size ());
455+ System .out .println ("Fix verification summary" );
456+ System .out .println ();
457+ System .out .println ("Total vulnerable test cases: " + vulnerableTestcases .size ());
458+ System .out .println (
459+ "\t Properly fixed (not exploitable):\t "
460+ + (vulnerableTestcases .size ()
461+ - exploitedModifiedVulnerableTestcases .size ()));
414462 System .out .println (
415- "\t Not verifiable fixed test cases:\t " + notVerifiableFixedTestcases .size ());
463+ "\t Not correctly fixed (still exploitable):\t "
464+ + exploitedModifiedVulnerableTestcases .size ());
465+ System .out .println (
466+ "\t Not auto-verifiable (can't tell if exploitable):\t "
467+ + notVerifiableModifiedVulnerableTestcases .size ());
468+ System .out .println (
469+ "\t Functionality broken/modified:\t " + brokenModifiedVulnerableTestcases .size ());
470+ System .out .println ();
471+ System .out .println ("Total not vulnerable test cases: " + notVulnerableTestcases .size ());
472+ System .out .println (
473+ "\t Still not exploitable:\t "
474+ + (notVulnerableTestcases .size ()
475+ - exploitedModifiedNotVulnerableTestcases .size ()));
476+ System .out .println ("\t Now exploitable:\t " + exploitedModifiedNotVulnerableTestcases .size ());
477+ System .out .println (
478+ "\t Not auto-verifiable (can't tell if exploitable):\t "
479+ + notVerifiableModifiedNotVulnerableTestcases .size ());
480+ System .out .println (
481+ "\t Functionality broken/modified:\t " + brokenModifiedNotVulnerableTestcases .size ());
416482 }
417483
418484 /**
@@ -538,27 +604,39 @@ protected void handleResponse(TestCaseVerificationResults results)
538604 .getTestCase ()
539605 .getName ()
540606 .equals (fixedResults .getTestCase ().getName ())) {
541- // FIXME: Generalize this so it can support languages other than Java and multiple
542- // source files per testcase.
543- String unfixedSourceFile =
544- Paths .get (unfixedSourceDirectory , unfixedResults .getTestCase ().getName ())
545- .toString ()
546- + ".java" ;
547- String fixedSourceFile =
548- Paths .get (fixedSourceDirectory , fixedResults .getTestCase ().getName ())
549- .toString ()
550- + ".java" ;
551- String unfixedSourceFileContents =
552- new String (Files .readAllBytes (Paths .get (unfixedSourceFile )));
553- String fixedSourceFileContents =
554- new String (Files .readAllBytes (Paths .get (fixedSourceFile )));
555- if (!unfixedSourceFileContents .equals (fixedSourceFileContents )) {
607+
608+ // // FIXME: Generalize this so it can support languages other than Java and
609+ // multiple
610+ // // source files per testcase.
611+ // String unfixedSourceFile =
612+ // Paths.get(unfixedSourceDirectory, unfixedResults.getTestCase().getName())
613+ // .toString()
614+ // + ".java";
615+ // String fixedSourceFile =
616+ // Paths.get(fixedSourceDirectory, fixedResults.getTestCase().getName())
617+ // .toString()
618+ // + ".java";
619+ // String unfixedSourceFileContents =
620+ // new String(Files.readAllBytes(Paths.get(unfixedSourceFile)));
621+ // String fixedSourceFileContents =
622+ // new String(Files.readAllBytes(Paths.get(fixedSourceFile)));
623+
624+ // // Skip testcase in verifyFixed mode if fixed source code is unchanged.
625+ // if (Boolean.parseBoolean(verifyFixed)
626+ // && unfixedSourceFileContents.equals(fixedSourceFileContents)) {
627+ // // System.out.println(
628+ // // "WARNING: Testcase "
629+ // // + fixedResults.getTestCase().getName()
630+ // // + " source file unmodified");
631+ // } else {
632+ // verifyFix(unfixedResults, fixedResults);
633+ // }
634+ if (Boolean .parseBoolean (verifyFixed )
635+ && isTestCaseModified (
636+ unfixedSourceDirectory ,
637+ fixedSourceDirectory ,
638+ unfixedResults .getTestCase ().getName ())) {
556639 verifyFix (unfixedResults , fixedResults );
557- } else {
558- System .out .println (
559- "WARNING: Testcase "
560- + fixedResults .getTestCase ().getName ()
561- + " source file unmodified" );
562640 }
563641 } else {
564642 System .out .println (
@@ -612,59 +690,78 @@ private TestCaseVerificationResultsCollection loadTestCaseVerificationResults(
612690 }
613691
614692 private boolean verifyFix (
615- TestCaseVerificationResults beforeFixResults ,
616- TestCaseVerificationResults afterFixResults ) {
693+ TestCaseVerificationResults unfixedResults , TestCaseVerificationResults fixedResults ) {
694+
695+ // DEBUG
696+ try {
697+ String unfixedResultsJson = Utils .objectToJson (unfixedResults );
698+ System .out .println ("unfixedResults JSON: " + unfixedResultsJson );
699+ } catch (Exception e ) {
700+ e .printStackTrace ();
701+ }
617702
618- boolean wasNotVerifiable =
619- afterFixResults .getTestCase ().isVulnerability ()
620- && afterFixResults .getTestCase ().isUnverifiable ()
621- && afterFixResults .isPassed ();
703+ boolean isVulnerable = fixedResults .getTestCase ().isVulnerability ();
704+ // boolean wasNotVerifiable =
705+ // fixedResults.getTestCase().isVulnerability()
706+ // && fixedResults.getTestCase().isUnverifiable()
707+ // && fixedResults.isPassed();
708+ boolean wasNotVerifiable = fixedResults .getTestCase ().isUnverifiable ();
622709 boolean wasExploited =
623- afterFixResults .getTestCase ().isVulnerability ()
624- && !afterFixResults .getTestCase ().isUnverifiable ()
625- && afterFixResults .isPassed ();
626- boolean wasBroken =
627- !beforeFixResults
628- .getResponseToSafeValue ()
629- .getResponseString ()
630- .equals (afterFixResults .getResponseToSafeValue ().getResponseString ());
710+ fixedResults .getTestCase ().isVulnerability ()
711+ && !fixedResults .getTestCase ().isUnverifiable ()
712+ && fixedResults .isPassed ();
713+ boolean wasBroken = false ;
714+ if (fixedResults .getTestCase ().isUnverifiable ()) {
715+ wasBroken = false ;
716+ } else {
717+ // There will be no safe response info if testcase is not verifiable.
718+ wasBroken =
719+ !unfixedResults
720+ .getResponseToSafeValue ()
721+ .getResponseString ()
722+ .equals (fixedResults .getResponseToSafeValue ().getResponseString ());
723+ }
631724
632725 VerifyFixOutput verifyFixOutput = new VerifyFixOutput ();
633- verifyFixOutput .setTestCaseName (afterFixResults .getTestCase ().getName ());
634- verifyFixOutput .setUnfixedSafeResponseInfo (beforeFixResults .getResponseToSafeValue ());
635- verifyFixOutput .setUnfixedAttackResponseInfo (beforeFixResults .getResponseToAttackValue ());
636- verifyFixOutput .setFixedSafeResponseInfo (afterFixResults .getResponseToSafeValue ());
637- verifyFixOutput .setFixedAttackResponseInfo (afterFixResults .getResponseToAttackValue ());
726+ verifyFixOutput .setTestCaseName (fixedResults .getTestCase ().getName ());
727+ verifyFixOutput .setUnfixedSafeResponseInfo (unfixedResults .getResponseToSafeValue ());
728+ verifyFixOutput .setUnfixedAttackResponseInfo (unfixedResults .getResponseToAttackValue ());
729+ verifyFixOutput .setFixedSafeResponseInfo (fixedResults .getResponseToSafeValue ());
730+ verifyFixOutput .setFixedAttackResponseInfo (fixedResults .getResponseToAttackValue ());
638731 verifyFixOutput .setWasNotVerifiable (wasNotVerifiable );
639732 verifyFixOutput .setWasExploited (wasExploited );
640733 verifyFixOutput .setWasBroken (wasBroken );
641734
642- if (wasNotVerifiable ) {
643- System .out .println ("NOT FIXED: Vulnerability could not be verified" );
644- notVerifiableFixedTestcases .add (verifyFixOutput );
645- }
646- if (wasExploited ) {
647- System .out .println ("NOT FIXED: Vulnerability was exploited" );
648- exploitedFixedTestcases .add (verifyFixOutput );
649- }
650- if (wasBroken ) {
651- System .out .println ("NOT FIXED: Functionality was broken" );
652- brokenFixedTestcases .add (verifyFixOutput );
735+ if (isVulnerable ) {
736+ vulnerableTestcases .add (verifyFixOutput );
737+ if (wasNotVerifiable ) {
738+ System .out .println ("NOT FIXED: Vulnerability could not be verified" );
739+ notVerifiableModifiedVulnerableTestcases .add (verifyFixOutput );
740+ } else {
741+ if (wasExploited ) {
742+ System .out .println ("NOT FIXED: Vulnerability was exploited" );
743+ exploitedModifiedVulnerableTestcases .add (verifyFixOutput );
744+ }
745+ if (wasBroken ) {
746+ System .out .println ("NOT FIXED: Functionality was broken" );
747+ brokenModifiedVulnerableTestcases .add (verifyFixOutput );
748+ }
749+ }
750+ } else {
751+ notVulnerableTestcases .add (verifyFixOutput );
752+ if (wasNotVerifiable ) {
753+ notVerifiableModifiedNotVulnerableTestcases .add (verifyFixOutput );
754+ } else {
755+ if (wasExploited ) {
756+ exploitedModifiedNotVulnerableTestcases .add (verifyFixOutput );
757+ }
758+ if (wasBroken ) {
759+ brokenModifiedNotVulnerableTestcases .add (verifyFixOutput );
760+ }
761+ }
653762 }
654763
655- File verifyFixResultFile = new File (getOutputDirectory (), FILENAME_VERIFY_FIX_RESULT );
656- try (BufferedWriter writer = new BufferedWriter (new FileWriter (verifyFixResultFile ))) {
657- String output = Utils .objectToJson (verifyFixOutput );
658- // System.out.println(output);
659- writer .write (output );
660- } catch (IOException e ) {
661- System .out .println (
662- "ERROR: Could not write VerifyFixOutput to file " + verifyFixResultFile );
663- e .printStackTrace ();
664- } catch (JAXBException e ) {
665- System .out .println ("ERROR: Could not marshall VerifyFixOutput to JSON" );
666- e .printStackTrace ();
667- }
764+ verifyFixesOutputList .add (verifyFixOutput );
668765
669766 return !wasNotVerifiable && !wasExploited && !wasBroken ;
670767 }
0 commit comments