Skip to content

Commit 31470a4

Browse files
committed
Add ui to view cves of an image
1 parent 97aa6f9 commit 31470a4

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

src/main/java/io/gardenlinux/glvd/UiController.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.gardenlinux.glvd;
22

3+
import io.gardenlinux.glvd.db.ImageSourcePackageCve;
34
import io.gardenlinux.glvd.db.SourcePackageCve;
45
import io.gardenlinux.glvd.exceptions.CveNotKnownException;
56
import jakarta.annotation.Nonnull;
@@ -39,6 +40,33 @@ gardenlinuxVersion, new SortAndPageOptions(sortBy, sortOrder, pageNumber, pageSi
3940
return "getPackagesForDistro";
4041
}
4142

43+
@GetMapping("/getCveForImage")
44+
public String getCveForImage(
45+
@RequestParam(name = "gardenlinuxVersion", required = true) String gardenlinuxVersion,
46+
@RequestParam(name = "imageName", required = true) String imageName,
47+
@RequestParam(defaultValue = "baseScore") final String sortBy,
48+
@RequestParam(defaultValue = "DESC") final String sortOrder,
49+
@RequestParam(required = false) final String pageNumber,
50+
@RequestParam(required = false) final String pageSize,
51+
@RequestParam(required = false, defaultValue = "true") final boolean onlyVulnerable,
52+
Model model
53+
) {
54+
var sourcePackageCves = glvdService.getCveForImage(
55+
imageName, gardenlinuxVersion, new SortAndPageOptions(sortBy, sortOrder, pageNumber, pageSize)
56+
)
57+
.stream()
58+
.filter(ImageSourcePackageCve::isVulnerable)
59+
.filter(sourcePackageCve -> !sourcePackageCve.getVulnStatus().equalsIgnoreCase("Rejected"))
60+
.toList();
61+
var contexts = glvdService.getCveContextsForDist(glvdService.distVersionToId(gardenlinuxVersion));
62+
model.addAttribute("sourcePackageCves", sourcePackageCves);
63+
model.addAttribute("gardenlinuxVersion", gardenlinuxVersion);
64+
model.addAttribute("imageName", imageName);
65+
model.addAttribute("onlyVulnerable", onlyVulnerable);
66+
model.addAttribute("cveContexts", contexts);
67+
return "getCveForImage";
68+
}
69+
4270
@GetMapping("/getCveForDistribution")
4371
public String getCveForDistribution(
4472
@RequestParam(name = "gardenlinuxVersion", required = true) String gardenlinuxVersion,

src/main/resources/static/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393

9494
document.addEventListener("DOMContentLoaded", function () {
9595
populateGardenlinuxVersions("gardenlinuxVersion");
96+
populateGardenlinuxVersions("imageGardenlinuxVersion");
9697
populateGardenlinuxVersions("triageGardenlinuxVersion");
9798
populateGardenlinuxVersions("packagesGardenlinuxVersion");
9899
populateGardenlinuxVersions("distroGardenlinuxVersion");
@@ -135,6 +136,16 @@ <h1>Welcome to the Garden Linux Vulnerability Database</h1>
135136
<td><button type="submit">Go</button>
136137
</form>
137138
</tr>
139+
<tr>
140+
<td><form action="/getCveForImage" method="get" class="distribution">
141+
<label for="gardenlinuxVersion">...an Garden Linux image</label>
142+
<td><input id="imageName" name="imageName" type="text" placeholder="gcp-gardener_prod" required />
143+
<td><select id="imageGardenlinuxVersion" name="gardenlinuxVersion" required>
144+
<option value="">Loading...</option>
145+
</select>
146+
<td><button type="submit">Go</button>
147+
</form>
148+
</tr>
138149
<tr>
139150
<td><form action="/getTriage" method="get" class="triage">
140151
<label for="triageGardenlinuxVersion">...the Triage for a Garden Linux version</label>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<!DOCTYPE HTML>
2+
<html xmlns:th="http://www.thymeleaf.org">
3+
<head>
4+
<title>GLVD: List vulnerabilities in image</title>
5+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6+
<link href="style.css" rel="stylesheet" media="screen" />
7+
</head>
8+
<body>
9+
<h1 th:text="|Vulnerabilities list for Garden Linux image ${imageName} in version ${gardenlinuxVersion} |" />
10+
11+
<p th:text="|Found ${#lists.size(sourcePackageCves)} potential security issues|"></p>
12+
13+
<table>
14+
<thead>
15+
<tr>
16+
<th>CVE ID
17+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=cveId,sortOrder=ASC,onlyVulnerable=true)}">&uarr;</a>
18+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=cveId,sortOrder=DESC,onlyVulnerable=true)}">&darr;</a>
19+
</th>
20+
21+
<th>CVE Base Score
22+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=baseScore,sortOrder=ASC,onlyVulnerable=true)}">&uarr;</a>
23+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=baseScore,sortOrder=DESC,onlyVulnerable=true)}">&darr;</a>
24+
</th>
25+
26+
<th>Vector String</th>
27+
28+
<th>CVE Published Date
29+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=cvePublishedDate,sortOrder=ASC,onlyVulnerable=true)}">&uarr;</a>
30+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=cvePublishedDate,sortOrder=DESC,onlyVulnerable=true)}">&darr;</a>
31+
</th>
32+
33+
<th>CVE Last Modified Date
34+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=cveLastModifiedDate,sortOrder=ASC,onlyVulnerable=true)}">&uarr;</a>
35+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=cveLastModifiedDate,sortOrder=DESC,onlyVulnerable=true)}">&darr;</a>
36+
</th>
37+
38+
<th>CVE Last Ingested Date
39+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=cveLastIngestedDate,sortOrder=ASC,onlyVulnerable=true)}">&uarr;</a>
40+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=cveLastIngestedDate,sortOrder=DESC,onlyVulnerable=true)}">&darr;</a>
41+
</th>
42+
43+
<th>Source Package
44+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=sourcePackageName,sortOrder=ASC,onlyVulnerable=true)}">&uarr;</a>
45+
<a th:href="@{/getCveForImage(gardenlinuxVersion=${gardenlinuxVersion},imageName=${imageName},sortBy=sourcePackageName,sortOrder=DESC,onlyVulnerable=true)}">&darr;</a>
46+
</th>
47+
48+
<th>Version</th>
49+
<th>Is Vulnerable?</th>
50+
<th>Vulnerability Status</th>
51+
</tr>
52+
</thead>
53+
<tr th:each="item: ${sourcePackageCves}">
54+
<td><a th:href="@{/getCveDetails(cveId=${item.cveId})}"> <div th:text="[DETAILS]"></div> </a> <div th:text="${item.cveId}"/> </td>
55+
<td th:text="${item.baseScore}" />
56+
<td th:text="${item.vectorString}" />
57+
<td th:text="${item.cvePublishedDate}" />
58+
<td th:text="${item.cveLastModifiedDate}" />
59+
<td th:text="${item.cveLastIngestedDate}" />
60+
<td th:text="${item.sourcePackageName}" />
61+
<td th:text="${item.sourcePackageVersion}" />
62+
<td th:text="${item.isVulnerable}" />
63+
<td th:text="${item.vulnStatus}" />
64+
</tr>
65+
</table>
66+
67+
<h2 th:text="|CVE Contexts for Garden Linux ${gardenlinuxVersion} |" />
68+
69+
<table>
70+
<thead>
71+
<tr>
72+
<th>CVE ID</th>
73+
<th>Create Date</th>
74+
<th>Use-Case</th>
75+
<th>Description</th>
76+
<th>Is Resolved?</th>
77+
</tr>
78+
</thead>
79+
<tr th:each="item: ${cveContexts}">
80+
<td><a th:href="@{/getCveDetails(cveId=${item.cveId})}"> <div th:text="[DETAILS]"></div> </a> <div th:text="${item.cveId}"/> </td>
81+
<td th:text="${item.createDate}"></td>
82+
<td th:text="${item.useCase}"></td>
83+
<td th:text="${item.description}"></td>
84+
<td th:text="${item.getResolved}"></td>
85+
</tr>
86+
</table>
87+
88+
</body>
89+
</html>

0 commit comments

Comments
 (0)