|
12 | 12 | import com.google.gson.JsonArray; |
13 | 13 | import com.google.gson.JsonElement; |
14 | 14 | import com.google.gson.JsonObject; |
15 | | -import com.google.gson.JsonParseException; |
16 | 15 | import com.google.gson.JsonParser; |
17 | 16 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; |
18 | 17 | import hudson.EnvVars; |
@@ -707,7 +706,7 @@ public void perform(Run<?, ?> build, FilePath workspace, EnvVars env, Launcher l |
707 | 706 |
|
708 | 707 | if (isEpssThresholdEnabled && epssThreshold != null) { |
709 | 708 | listener.getLogger().println("EPSS Threshold set to: " + epssThreshold); |
710 | | - boolean cvesExceedThreshold = assessCVEsAgainstEPSS(build, workspace, listener, epssThreshold, sbomWorkspacePath); |
| 709 | + boolean cvesExceedThreshold = assessCVEsAgainstEPSS(listener, epssThreshold, sbomData); |
711 | 710 | if (cvesExceedThreshold) { |
712 | 711 | doesBuildPass = false; |
713 | 712 | } |
@@ -738,86 +737,66 @@ public void perform(Run<?, ?> build, FilePath workspace, EnvVars env, Launcher l |
738 | 737 | } |
739 | 738 | } |
740 | 739 |
|
741 | | - private boolean assessCVEsAgainstEPSS(Run<?, ?> build, FilePath workspace, TaskListener listener, Double epssThreshold, String sbomPath) |
742 | | - throws IOException, InterruptedException { |
743 | | - FilePath sbomFile = workspace.child(sbomPath); |
744 | | - if (!sbomFile.exists()) { |
745 | | - listener.getLogger().println("SBOM file not found at: " + sbomFile.getRemote()); |
746 | | - return true; |
| 740 | + private boolean assessCVEsAgainstEPSS(TaskListener listener, Double epssThreshold, SbomData sbomData) { |
| 741 | + List<Vulnerability> vulnerabilities = sbomData.getSbom().getVulnerabilities(); |
| 742 | + if (vulnerabilities == null || vulnerabilities.isEmpty()) { |
| 743 | + listener.getLogger().println("No vulnerabilities found in the scan response."); |
| 744 | + return false; |
747 | 745 | } |
748 | | - try { |
749 | | - String sbomContent = sbomFile.readToString(); |
750 | | - listener.getLogger().println("SBOM file read successfully."); |
751 | | - Gson gson = new Gson(); |
752 | | - Sbom sbom = gson.fromJson(sbomContent, Sbom.class); |
753 | | - listener.getLogger().println("SBOM JSON parsed successfully."); |
754 | | - List<Vulnerability> vulnerabilities = sbom.getVulnerabilities(); |
755 | | - if (vulnerabilities == null || vulnerabilities.isEmpty()) { |
756 | | - listener.getLogger().println("No vulnerabilities found in the SBOM."); |
757 | | - return false; |
| 746 | + |
| 747 | + Set<String> suppressedCveSet = new HashSet<>(); |
| 748 | + if (isSuppressedCveEnabled && suppressedCveList != null && !suppressedCveList.trim().isEmpty()) { |
| 749 | + String[] cveArray = suppressedCveList.split("[,\\n\\r]+"); |
| 750 | + for (String cve : cveArray) { |
| 751 | + suppressedCveSet.add(cve.trim().toUpperCase()); |
758 | 752 | } |
759 | | - |
760 | | - Set<String> suppressedCveSet = new HashSet<>(); |
761 | | - if (isSuppressedCveEnabled && suppressedCveList != null && !suppressedCveList.trim().isEmpty()) { |
762 | | - String[] cveArray = suppressedCveList.split("[,\\n\\r]+"); |
763 | | - for (String cve : cveArray) { |
764 | | - suppressedCveSet.add(cve.trim().toUpperCase()); |
765 | | - } |
766 | | - listener.getLogger().println("Suppressing " + suppressedCveSet.size() + " CVEs from EPSS assessment: " + suppressedCveSet); |
| 753 | + listener.getLogger().println("Suppressing " + suppressedCveSet.size() + " CVEs from EPSS assessment: " + suppressedCveSet); |
| 754 | + } |
| 755 | + |
| 756 | + listener.getLogger().println("Starting EPSS assessment for vulnerabilities..."); |
| 757 | + boolean exceedsThreshold = false; |
| 758 | + Map<String, Double> exceedingCVEsMap = new HashMap<>(); |
| 759 | + int suppressedCount = 0; |
| 760 | + |
| 761 | + for (Vulnerability vulnerability : vulnerabilities) { |
| 762 | + String cveId = vulnerability.getId(); |
| 763 | + Double epssScore = vulnerability.getEpssScore(); |
| 764 | + |
| 765 | + if (suppressedCveSet.contains(cveId.toUpperCase())) { |
| 766 | + suppressedCount++; |
| 767 | + continue; |
767 | 768 | } |
768 | | - |
769 | | - listener.getLogger().println("Starting EPSS assessment for vulnerabilities..."); |
770 | | - boolean exceedsThreshold = false; |
771 | | - Map<String, Double> exceedingCVEsMap = new HashMap<>(); |
772 | | - int suppressedCount = 0; |
773 | | - |
774 | | - for (Vulnerability vulnerability : vulnerabilities) { |
775 | | - String cveId = vulnerability.getId(); |
776 | | - Double epssScore = vulnerability.getEpssScore(); |
777 | | - |
778 | | - // Skip suppressed CVEs |
779 | | - if (suppressedCveSet.contains(cveId.toUpperCase())) { |
780 | | - suppressedCount++; |
781 | | - continue; |
782 | | - } |
783 | | - |
784 | | - if (epssScore == null) { |
785 | | - continue; |
786 | | - } |
787 | | - if (epssScore >= epssThreshold) { |
788 | | - exceedsThreshold = true; |
789 | | - exceedingCVEsMap.put(cveId, epssScore); |
790 | | - } |
| 769 | + |
| 770 | + if (epssScore == null) { |
| 771 | + continue; |
791 | 772 | } |
792 | | - |
793 | | - if (suppressedCount > 0) { |
794 | | - listener.getLogger().println("Suppressed " + suppressedCount + " CVEs from EPSS assessment."); |
| 773 | + if (epssScore >= epssThreshold) { |
| 774 | + exceedsThreshold = true; |
| 775 | + exceedingCVEsMap.put(cveId, epssScore); |
795 | 776 | } |
796 | | - |
797 | | - if (exceedsThreshold) { |
798 | | - listener.getLogger().println("The following CVEs exceed the EPSS threshold of " + epssThreshold + ":"); |
799 | | - int count = 0; |
800 | | - for (Map.Entry<String, Double> entry : exceedingCVEsMap.entrySet()) { |
801 | | - if (count < MAX_EPSS_CVES_CONSOLE) { |
802 | | - listener.getLogger().println(String.format(" - %s (EPSS: %.3f)", entry.getKey(), entry.getValue())); |
803 | | - count++; |
804 | | - } else { |
805 | | - listener.getLogger().println(" ... and " + (exceedingCVEsMap.size() - count) + " more EPSS breaches (check assessment file for complete list)"); |
806 | | - break; |
807 | | - } |
| 777 | + } |
| 778 | + |
| 779 | + if (suppressedCount > 0) { |
| 780 | + listener.getLogger().println("Suppressed " + suppressedCount + " CVEs from EPSS assessment."); |
| 781 | + } |
| 782 | + |
| 783 | + if (exceedsThreshold) { |
| 784 | + listener.getLogger().println("The following CVEs exceed the EPSS threshold of " + epssThreshold + ":"); |
| 785 | + int count = 0; |
| 786 | + for (Map.Entry<String, Double> entry : exceedingCVEsMap.entrySet()) { |
| 787 | + if (count < MAX_EPSS_CVES_CONSOLE) { |
| 788 | + listener.getLogger().println(String.format(" - %s (EPSS: %.3f)", entry.getKey(), entry.getValue())); |
| 789 | + count++; |
| 790 | + } else { |
| 791 | + listener.getLogger().println(" ... and " + (exceedingCVEsMap.size() - count) + " more EPSS breaches (check assessment file for complete list)"); |
| 792 | + break; |
808 | 793 | } |
809 | | - listener.getLogger().println("Failing the build due to EPSS threshold breach."); |
810 | | - } else { |
811 | | - listener.getLogger().println("All assessed CVEs are within the EPSS threshold of " + epssThreshold + "."); |
812 | 794 | } |
813 | | - return exceedsThreshold; |
814 | | - } catch (JsonParseException e) { |
815 | | - listener.getLogger().println("Invalid JSON structure in SBOM file: " + e.getMessage()); |
816 | | - return true; |
817 | | - } catch (IOException e) { |
818 | | - listener.getLogger().println("Error reading SBOM file: " + e.getMessage()); |
819 | | - return true; |
| 795 | + listener.getLogger().println("Failing the build due to EPSS threshold breach."); |
| 796 | + } else { |
| 797 | + listener.getLogger().println("All assessed CVEs are within the EPSS threshold of " + epssThreshold + "."); |
820 | 798 | } |
| 799 | + return exceedsThreshold; |
821 | 800 | } |
822 | 801 |
|
823 | 802 | private String getOidcToken(IdTokenStringCredentials oidcStr, IdTokenFileCredentials oidcFile) throws IOException { |
|
0 commit comments