Skip to content

Commit

Permalink
added parser for grype report
Browse files Browse the repository at this point in the history
  • Loading branch information
dtbaum committed Jul 26, 2023
1 parent 34f81e1 commit 4dc09c0
Show file tree
Hide file tree
Showing 6 changed files with 4,165 additions and 1 deletion.
18 changes: 17 additions & 1 deletion SUPPORTED-FORMATS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--- DO NOT EDIT -- Generated at 2023-05-05T12:05:52.316441 - Run the `main` method of `ParserRegistry` to regenerate after changing parsers -- DO NOT EDIT --->
<!--- DO NOT EDIT -- Generated at 2023-07-02T18:56:49.380384255 - Run the `main` method of `ParserRegistry` to regenerate after changing parsers -- DO NOT EDIT --->
# Supported Report Formats

The static analysis model supports the following report formats.
Expand Down Expand Up @@ -938,6 +938,22 @@ If your tool is supported, but some properties are missing (icon, URL, etc.), pl
-
</td>
</tr>
<tr>
<td>
grypescanner
</td>
<td>
<img src="https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png" alt="Grype scanner" height="64" width="64">
</td>
<td>
<a href="https://github.com/anchore/grype">
Grype scanner
</a>
</td>
<td>
/tmp/1.json
</td>
</tr>
<tr>
<td>
hadolint
Expand Down
66 changes: 66 additions & 0 deletions src/main/java/edu/hm/hafner/analysis/parser/GrypeParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package edu.hm.hafner.analysis.parser;

import edu.hm.hafner.analysis.Issue;
import edu.hm.hafner.analysis.IssueBuilder;
import edu.hm.hafner.analysis.Report;
import edu.hm.hafner.analysis.Severity;
import edu.umd.cs.findbugs.annotations.CheckForNull;

Check warning on line 7 in src/main/java/edu/hm/hafner/analysis/parser/GrypeParser.java

View check run for this annotation

ci.jenkins.io / PMD

UnnecessaryImport

NORMAL: Unused import 'edu.umd.cs.findbugs.annotations.CheckForNull'.
Raw output
Reports import statements that can be removed. They are either unused, duplicated, or the members they import are already implicitly in scope, because they're in java.lang, or the current package. <pre> <code> import java.io.File; // not used, can be removed import java.util.Collections; // used below import java.util.*; // so this one is not used import java.lang.Object; // imports from java.lang, unnecessary import java.lang.Object; // duplicate, unnecessary public class Foo { static Object emptyList() { return Collections.emptyList(); } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_codestyle.html#unnecessaryimport"> See PMD documentation. </a>
import org.json.JSONArray;
import org.json.JSONObject;

import static java.lang.String.*;

Check warning on line 11 in src/main/java/edu/hm/hafner/analysis/parser/GrypeParser.java

View check run for this annotation

ci.jenkins.io / PMD

UnnecessaryImport

NORMAL: Unused import 'java.lang.String.*'.
Raw output
Reports import statements that can be removed. They are either unused, duplicated, or the members they import are already implicitly in scope, because they're in java.lang, or the current package. <pre> <code> import java.io.File; // not used, can be removed import java.util.Collections; // used below import java.util.*; // so this one is not used import java.lang.Object; // imports from java.lang, unnecessary import java.lang.Object; // duplicate, unnecessary public class Foo { static Object emptyList() { return Collections.emptyList(); } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_codestyle.html#unnecessaryimport"> See PMD documentation. </a>

/**
* JSON report parser for grype (https://plugins.jenkins.io/grypescanner/ / https://github.com/anchore/grype).
*/
public class GrypeParser extends JsonIssueParser {
private static final long serialVersionUID = -1369431674771459756L;

private static final String MATCHES_TAG = "matches";
private static final String VULNERABILIY_TAG = "vulnerability";
private static final String ARTIFACT_TAG = "artifact";
private static final String LOCATIONS_TAG = "locations";
private static final String PATH_TAG = "path";
private static final String DATA_SOURCE_TAG = "dataSource";
private static final String SEVERITY_TAG = "severity";
private static final String ID_TAG = "id";
private static final String DESCRIPTION_TAG = "description";

@Override
protected void parseJsonObject(final Report report, final JSONObject jsonReport, final IssueBuilder issueBuilder) {
final JSONArray matches = jsonReport.getJSONArray(MATCHES_TAG);
for (int i = 0; i < matches.length(); i++) {
final JSONObject match = matches.getJSONObject(i);
if (!match.has(VULNERABILIY_TAG)) {
continue;
}
JSONObject vuln = match.getJSONObject(VULNERABILIY_TAG);
String fileName = match.getJSONObject(ARTIFACT_TAG).getJSONArray(LOCATIONS_TAG).getJSONObject(0)
.getString(PATH_TAG);
Issue issue = issueBuilder.setFileName(fileName)
.setCategory(vuln.getString(SEVERITY_TAG))
.setSeverity(mapSeverity(vuln.getString(SEVERITY_TAG)))
.setType(vuln.getString(ID_TAG))
.setMessage(vuln.getString(DESCRIPTION_TAG))
.setOriginName("Grype")
.setPathName(fileName)
.setDescription(vuln.getString(DATA_SOURCE_TAG)).build();
report.add(issue);
}
}

private Severity mapSeverity(final String severity) {
switch (severity.toUpperCase()) {

Check warning on line 53 in src/main/java/edu/hm/hafner/analysis/parser/GrypeParser.java

View check run for this annotation

ci.jenkins.io / SpotBugs

DM_CONVERT_CASE

LOW: Use of non-localized String.toUpperCase() or String.toLowerCase() in edu.hm.hafner.analysis.parser.GrypeParser.mapSeverity(String)
Raw output
<p> A String is being converted to upper or lowercase, using the platform's default encoding. This may result in improper conversions when used with international characters. Use the </p> <ul> <li>String.toUpperCase( Locale l )</li> <li>String.toLowerCase( Locale l )</li> </ul> <p>versions instead.</p>

Check warning on line 53 in src/main/java/edu/hm/hafner/analysis/parser/GrypeParser.java

View check run for this annotation

ci.jenkins.io / SpotBugs

IMPROPER_UNICODE

LOW: Improper handling of Unicode transformations such as case mapping and normalization.
Raw output
no message found

Check warning on line 53 in src/main/java/edu/hm/hafner/analysis/parser/GrypeParser.java

View check run for this annotation

ci.jenkins.io / PMD

UseLocaleWithCaseConversions

NORMAL: When doing a String.toLowerCase()/toUpperCase() call, use a Locale.
Raw output
When doing `String::toLowerCase()/toUpperCase()` conversions, use an explicit locale argument to specify the case transformation rules. Using `String::toLowerCase()` without arguments implicitly uses `Locale::getDefault()`. The problem is that the default locale depends on the current JVM setup (and usually on the system in which it is running). Using the system default may be exactly what you want (e.g. if you are manipulating strings you got through standard input), but it may as well not be the case (e.g. if you are getting the string over the network or a file, and the encoding is well-defined and independent of the environment). In the latter case, using the default locale makes the case transformation brittle, as it may yield unexpected results on a machine whose locale has other case translation rules. For example, in Turkish, the uppercase form of `i` is `İ` (U+0130, not ASCII) and not `I` (U+0049) as in English. The rule is intended to *force* developers to think about locales when dealing with strings. By taking a conscious decision about the choice of locale at the time of writing, you reduce the risk of surprising behaviour down the line, and communicate your intent to future readers. <pre> <code> // violation - implicitly system-dependent conversion if (x.toLowerCase().equals(&quot;list&quot;)) {} // The above will not match &quot;LIST&quot; on a system with a Turkish locale. // It could be replaced with if (x.toLowerCase(Locale.US).equals(&quot;list&quot;)) { } // or simply if (x.equalsIgnoreCase(&quot;list&quot;)) { } // ok - system independent conversion String z = a.toLowerCase(Locale.ROOT); // ok - explicit system-dependent conversion String z2 = a.toLowerCase(Locale.getDefault()); </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_errorprone.html#uselocalewithcaseconversions"> See PMD documentation. </a>
case "LOW":
return Severity.WARNING_LOW;
case "MEDIUM":
return Severity.WARNING_NORMAL;
case "CRITICAL":
return Severity.ERROR;
case "HIGH":
return Severity.WARNING_HIGH;
default:
return new Severity(severity);
}
}
}
37 changes: 37 additions & 0 deletions src/main/java/edu/hm/hafner/analysis/registry/GrypeDescriptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package edu.hm.hafner.analysis.registry;

import edu.hm.hafner.analysis.IssueParser;
import edu.hm.hafner.analysis.parser.GrypeParser;

/**
* Descriptor for Grype report parser.
*/
public class GrypeDescriptor extends ParserDescriptor {
private static final String ID = "grypescanner";
private static final String NAME = "Grype scanner";

GrypeDescriptor() {
super(ID, NAME);
}

@Override
public IssueParser createParser(final Option... options) {
return new GrypeParser();
}

@Override
public String getPattern() {
return "**/grype-report.json";

Check warning on line 24 in src/main/java/edu/hm/hafner/analysis/registry/GrypeDescriptor.java

View check run for this annotation

ci.jenkins.io / CheckStyle

FileTabCharacterCheck

NORMAL: File contains tab characters (this is the first instance).
Raw output
<p>Since Checkstyle 5.0</p><p> Checks that there are no tab characters (<code>'\t'</code>) in the source code. </p><p> Rationale: </p><ul><li> Developers should not need to configure the tab width of their text editors in order to be able to read source code. </li><li> From the Apache jakarta coding standards: In a distributed development environment, when the commit messages get sent to a mailing list, they are almost impossible to read if you use tabs. </li></ul>
}

@Override
public String getUrl() {
return "https://github.com/anchore/grype";
}

@Override
public String getIconUrl() {
return "https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png";
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package edu.hm.hafner.analysis.registry;

import j2html.tags.ContainerTag;
import j2html.tags.DomContent;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -92,6 +94,7 @@ public class ParserRegistry {
new GnuFortranDescriptor(),
new GoLintDescriptor(),
new GoVetDescriptor(),
new GrypeDescriptor(),
new HadoLintDescriptor(),
new IarCstatDescriptor(),
new IarDescriptor(),
Expand Down
40 changes: 40 additions & 0 deletions src/test/java/edu/hm/hafner/analysis/parser/GrypeParserTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package edu.hm.hafner.analysis.parser;

import edu.hm.hafner.analysis.AbstractParserTest;
import edu.hm.hafner.analysis.IssueParser;
import edu.hm.hafner.analysis.Report;
import edu.hm.hafner.analysis.Severity;
import edu.hm.hafner.analysis.assertions.SoftAssertions;

class GrypeParserTest extends AbstractParserTest {
protected GrypeParserTest() {
super("grype-report.json");
}

@Override
protected void assertThatIssuesArePresent(final Report report, final SoftAssertions softly) {
softly.assertThat(report).hasSize(29).hasDuplicatesSize(0);
softly.assertThat(report.get(0))
.hasFileName("tomcat-jdbc/8.0.28/tomcat-jdbc-8.0.28.jar")
.hasSeverity(Severity.WARNING_NORMAL)
.hasCategory("Medium")
.hasType("CVE-2015-5345")
.hasMessage(
"The Mapper component in Apache Tomcat 6.x before 6.0.45, 7.x before 7.0.68, 8.x before 8.0.30, and 9.x before 9.0.0.M2 processes redirects before considering security constraints and Filters, which allows remote attackers to determine the existence of a directory via a URL that lacks a trailing / (slash) character.")
.hasDescription("https://nvd.nist.gov/vuln/detail/CVE-2015-5345");

softly.assertThat(report.get(17))
.hasFileName("tomcat-jdbc/8.0.28/tomcat-jdbc-8.0.28.jar")
.hasSeverity(Severity.WARNING_HIGH)
.hasCategory("High")
.hasType("CVE-2016-8745")
.hasMessage(
"A bug in the error handling of the send file code for the NIO HTTP connector in Apache Tomcat 9.0.0.M1 to 9.0.0.M13, 8.5.0 to 8.5.8, 8.0.0.RC1 to 8.0.39, 7.0.0 to 7.0.73 and 6.0.16 to 6.0.48 resulted in the current Processor object being added to the Processor cache multiple times. This in turn meant that the same Processor could be used for concurrent requests. Sharing a Processor can result in information leakage between requests including, not not limited to, session ID and the response body. The bug was first noticed in 8.5.x onwards where it appears the refactoring of the Connector code for 8.5.x onwards made it more likely that the bug was observed. Initially it was thought that the 8.5.x refactoring introduced the bug but further investigation has shown that the bug is present in all currently supported Tomcat versions.")
.hasDescription("https://nvd.nist.gov/vuln/detail/CVE-2016-8745");
}

@Override
protected IssueParser createParser() {
return new GrypeParser();
}
}
Loading

0 comments on commit 4dc09c0

Please sign in to comment.