]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-22914 Define CVE message in the scanner report
authorJulien HENRY <julien.henry@sonarsource.com>
Tue, 3 Sep 2024 06:25:54 +0000 (08:25 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 12 Sep 2024 20:02:54 +0000 (20:02 +0000)
sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/FileStructure.java
sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportReader.java
sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportWriter.java
sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/viewer/ScannerReportViewerApp.java
sonar-scanner-protocol/src/main/protobuf/scanner_report.proto
sonar-scanner-protocol/src/test/java/org/sonar/scanner/protocol/output/ScannerReportWriterTest.java

index f1d2f5cae806d1a50be2f3047447338ecf1669bf..a3fb8835fbab19f8db883e7c9272b13734846b94 100644 (file)
@@ -82,6 +82,10 @@ public class FileStructure {
     return new File(dir, "adhocrules.pb");
   }
 
+  public File cves() {
+    return new File(dir, "cves.pb");
+  }
+
   public File fileFor(Domain domain, int componentRef) {
     return new File(dir, domain.filePrefix + componentRef + domain.fileSuffix);
   }
index 422690db2b73fb7459473f10f515ad1e41a1fde7..4569a34789101fc30d3753b0ebadd1988e4851c9 100644 (file)
@@ -61,6 +61,14 @@ public class ScannerReportReader {
     return Protobuf.readStream(file, ScannerReport.AdHocRule.parser());
   }
 
+  public CloseableIterator<ScannerReport.Cve> readCves() {
+    File file = fileStructure.cves();
+    if (!fileExists(file)) {
+      return emptyCloseableIterator();
+    }
+    return Protobuf.readStream(file, ScannerReport.Cve.parser());
+  }
+
   public CloseableIterator<ScannerReport.Measure> readComponentMeasures(int componentRef) {
     File file = fileStructure.fileFor(FileStructure.Domain.MEASURES, componentRef);
     if (fileExists(file)) {
index 07990c803e80a4aa4830af89db38168039b311a0..20e5f30a1f0a5f5f54679f69c3c80880e1afe0c4 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.scanner.protocol.output;
 
+import com.google.protobuf.AbstractMessageLite;
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -77,11 +78,7 @@ public class ScannerReportWriter {
 
   public void appendComponentIssue(int componentRef, ScannerReport.Issue issue) {
     File file = fileStructure.fileFor(FileStructure.Domain.ISSUES, componentRef);
-    try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file, true))) {
-      issue.writeDelimitedTo(out);
-    } catch (Exception e) {
-      throw ContextException.of("Unable to write issue", e).addContext("file", file);
-    }
+    appendDelimitedTo(file, issue, "issue");
   }
 
   public File writeComponentChangedLines(int componentRef, ScannerReport.ChangedLines changedLines) {
@@ -92,28 +89,29 @@ public class ScannerReportWriter {
 
   public void appendComponentExternalIssue(int componentRef, ScannerReport.ExternalIssue issue) {
     File file = fileStructure.fileFor(FileStructure.Domain.EXTERNAL_ISSUES, componentRef);
-    try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file, true))) {
-      issue.writeDelimitedTo(out);
-    } catch (Exception e) {
-      throw ContextException.of("Unable to write external issue", e).addContext("file", file);
-    }
+    appendDelimitedTo(file, issue, "external issue");
   }
 
   public void appendAdHocRule(ScannerReport.AdHocRule adHocRule) {
     File file = fileStructure.adHocRules();
-    try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file, true))) {
-      adHocRule.writeDelimitedTo(out);
-    } catch (Exception e) {
-      throw ContextException.of("Unable to write ad hoc rule", e).addContext("file", file);
-    }
+    appendDelimitedTo(file, adHocRule, "ad hoc rule");
+  }
+
+  public void appendCve(ScannerReport.Cve cve) {
+    File file = fileStructure.cves();
+    appendDelimitedTo(file, cve, "cve");
   }
 
   public void appendComponentMeasure(int componentRef, ScannerReport.Measure measure) {
     File file = fileStructure.fileFor(FileStructure.Domain.MEASURES, componentRef);
+    appendDelimitedTo(file, measure, "measure");
+  }
+
+  private static void appendDelimitedTo(File file, AbstractMessageLite<?, ?> msg, String msgName) {
     try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file, true))) {
-      measure.writeDelimitedTo(out);
+      msg.writeDelimitedTo(out);
     } catch (Exception e) {
-      throw ContextException.of("Unable to write measure", e).addContext("file", file);
+      throw ContextException.of("Unable to write " + msgName, e).addContext("file", file);
     }
   }
 
index e21a64a8bed35d54ad6440ca7209e6edc99b4944..33928bb8fe21296f1b4cb56a9943abfc0eb1f135 100644 (file)
@@ -101,6 +101,8 @@ public class ScannerReportViewerApp {
   private JEditorPane activeRuleEditor;
   private JScrollPane adHocRuleTab;
   private JEditorPane adHocRuleEditor;
+  private JScrollPane cveTab;
+  private JEditorPane cveEditor;
   private JScrollPane qualityProfileTab;
   private JEditorPane qualityProfileEditor;
   private JScrollPane pluginTab;
@@ -199,6 +201,7 @@ public class ScannerReportViewerApp {
     loadComponents();
     updateActiveRules();
     updateAdHocRules();
+    updateCves();
     updateQualityProfiles();
     updatePlugins();
     updateMetadata();
@@ -402,6 +405,18 @@ public class ScannerReportViewerApp {
     }
   }
 
+  private void updateCves() {
+    cveEditor.setText("");
+
+    StringBuilder builder = new StringBuilder();
+    try (CloseableIterator<ScannerReport.Cve> cveCloseableIterator = reader.readCves()) {
+      while (cveCloseableIterator.hasNext()) {
+        builder.append(cveCloseableIterator.next().toString()).append("\n");
+      }
+      cveEditor.setText(builder.toString());
+    }
+  }
+
   private void updateQualityProfiles() {
     qualityProfileEditor.setText("");
 
@@ -594,6 +609,12 @@ public class ScannerReportViewerApp {
     adHocRuleEditor = new JEditorPane();
     adHocRuleTab.setViewportView(adHocRuleEditor);
 
+    cveTab = new JScrollPane();
+    tabbedPane.addTab("CVEs", null, cveTab, null);
+
+    cveEditor = new JEditorPane();
+    cveTab.setViewportView(cveEditor);
+
     qualityProfileTab = new JScrollPane();
     tabbedPane.addTab("Quality Profiles", null, qualityProfileTab, null);
 
index ec1ef8d57b6a8a179bd557308c1190a65d001508..fddf8881f3106e3e42e23e0ba0dcc8465755424a 100644 (file)
@@ -230,6 +230,17 @@ message AdHocRule {
   repeated Impact defaultImpacts = 8;
 }
 
+message Cve {
+  string cve_id = 1;
+  string description = 2;
+  float cvss_score = 3;
+  float epss_score = 4;
+  float epss_percentile = 5;
+  int64 published_date = 6;
+  int64 last_modified_date = 7;
+  repeated string cwe = 8;
+}
+
 enum IssueType {
   UNSET = 0;
   CODE_SMELL = 1;
index 613a9e23ffd6cb0ee381e9af0e40d4041a5930d0..368886e2265d35b471bc973ffdc81ff80c3006b5 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.scanner.protocol.output;
 
 import com.google.common.collect.Iterators;
 import java.io.File;
+import java.time.Instant;
 import java.util.List;
 import org.junit.Before;
 import org.junit.Rule;
@@ -147,6 +148,29 @@ public class ScannerReportWriterTest {
     }
   }
 
+  @Test
+  public void write_cve() {
+
+    // write data
+    ScannerReport.Cve cve = ScannerReport.Cve.newBuilder()
+      .setCveId("CVE-2023-20863")
+      .setDescription("In spring framework versions prior to 5.2.24 release+ ,5.3.27+ and 6.0.8+ , it is possible for a user to provide a specially crafted SpEL expression that may cause a denial-of-service (DoS) condition.")
+      .setCvssScore(6.5f)
+      .setEpssScore(0.00306f)
+      .setEpssPercentile(0.70277f)
+      .setPublishedDate(Instant.parse("2023-04-13T20:15:00Z").toEpochMilli())
+      .setLastModifiedDate(Instant.parse("2024-02-04T02:22:24.474Z").toEpochMilli())
+      .addCwe("CWE-400")
+      .build();
+    underTest.appendCve(cve);
+
+    File file = underTest.getFileStructure().cves();
+    assertThat(file).exists().isFile();
+    try (CloseableIterator<ScannerReport.Cve> read = Protobuf.readStream(file, ScannerReport.Cve.parser())) {
+      assertThat(Iterators.size(read)).isOne();
+    }
+  }
+
   @Test
   public void write_changed_lines() {
     assertThat(underTest.hasComponentData(FileStructure.Domain.CHANGED_LINES, 1)).isFalse();