Skip to content

Commit 7dbbe7b

Browse files
committed
feat(security): add grype and snyk scanners
1 parent 92e812f commit 7dbbe7b

File tree

28 files changed

+805
-664
lines changed

28 files changed

+805
-664
lines changed

docker/Dockerfile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,27 @@ ARG COMMIT_MSG=unknown
1414
ENV ATTACHED_DEVICES_PERMS="/var/run/docker.sock"
1515

1616
# Add yq for YAML processing
17-
# renovate: datasource=github-releases lookupName=mikefarah/yq
1817
ARG YQ_VERSION=v4.52.4
1918
RUN curl -sSf -L -o /usr/local/bin/yq "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${TARGETARCH}" \
2019
&& chmod +x /usr/local/bin/yq
2120

2221
# Add regctl for container digest checks
23-
# renovate: datasource=github-releases lookupName=regclient/regclient
2422
ARG REGCTL_VERSION=v0.11.2
2523
RUN curl -sSf -L -o /usr/local/bin/regctl "https://github.com/regclient/regclient/releases/download/${REGCTL_VERSION}/regctl-linux-${TARGETARCH}" \
2624
&& chmod +x /usr/local/bin/regctl
2725

2826
# Add trivy for container vulnerability scanning
2927
COPY --from=aquasec/trivy:0.69.3@sha256:bcc376de8d77cfe086a917230e818dc9f8528e3c852f7b1aff648949b6258d1c /usr/local/bin/trivy /usr/local/bin/trivy
3028

29+
# Add grype for container vulnerability scanning
30+
RUN curl -sSfL https://get.anchore.io/grype | sh -s -- -b /usr/local/bin
31+
32+
# Add snyk for container vulnerability scanning
33+
ARG SNYK_VERSION=v1.1303.2
34+
RUN SNYK_BINARY=$( [ "$TARGETARCH" = "amd64" ] && echo "snyk-alpine" || echo "snyk-alpine-arm64" ) && \
35+
curl -sSf -L -o /usr/local/bin/snyk "https://github.com/snyk/cli/releases/download/${SNYK_VERSION}/${SNYK_BINARY}" && \
36+
chmod +x /usr/local/bin/snyk
37+
3138
# Add composer for PHP package management
3239
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
3340

root/app/www/public/ajax/overview.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@
134134
</div>
135135
</div>
136136
</div>
137-
<?php if ($settingsTable['trivyEnabled']) { ?>
138-
<div class="bg-secondary p-2 w-100 rounded-end" style="cursor:pointer;" onclick="initPage('trivy')">
137+
<?php if ($settingsTable['securityEnabled']) { ?>
138+
<div class="bg-secondary p-2 w-100 rounded-end" style="cursor:pointer;" onclick="initPage('security')">
139139
<div class="d-flex flex-row">
140140
<span class="h5"><i class="fas fa-bug"></i> Vulnerabilities</span>
141141
</div>
Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,18 @@
99
require 'shared.php';
1010

1111
if ($_POST['m'] == 'init') {
12-
$containerList = apiRequest('stats/containers')['result']['result'];
13-
$trivy = new Trivy();
14-
$dbNotice = ($trivy->getDBSize() == 0 || $trivy->getJavaDBSize() == 0);
15-
$downloadDbCmd = sprintf(TrivyCLI::UPDATE_DB_SHELL, TRIVY_PATH);
16-
$downloadJavaDbCmd = sprintf(TrivyCLI::UPDATE_DB_JAVA_SHELL, TRIVY_PATH);
12+
$containerList = apiRequest('stats/containers')['result']['result'];
13+
$security = new Security();
1714
?>
1815
<ol class="breadcrumb rounded p-1 ps-2">
1916
<li class="breadcrumb-item"><a href="#" onclick="initPage('overview')"><?= $_SESSION['activeServerName'] ?></a><span class="ms-2">↦</span></li>
20-
<li class="breadcrumb-item active" aria-current="page">Trivy</li>
17+
<li class="breadcrumb-item active" aria-current="page">Security</li>
2118
</ol>
2219
<div class="bg-secondary rounded p-4">
2320
<div class="row">
2421
<div class="col-sm-12">
25-
<?php if ($dbNotice) { ?>
26-
<div class="col-sm-12">
27-
<div class="rounded m-2 p-2 bg-gray">
28-
It seems like this is your first time using Trivy.<br>
29-
To scan container images Trivy uses pre-populated vulnerability databases that need to be downloaded first.<br>
30-
This is usually an automatic process triggered by the scheduled cron task, but if you'd like to manually scan your containers now, you'll need to download the databases first.<br>
31-
Click on the Download icon next to the Dockwatch container.<br>
32-
Note: The DBs are ~2.3GB big, depending on your internet connection this could take a few minutes.
33-
</div>
34-
</div>
35-
<?php } ?>
3622
<div class="table-responsive">
37-
<table class="table table-no-squish" id="trivy-table">
23+
<table class="table table-no-squish" id="security-table">
3824
<thead>
3925
<tr>
4026
<th scope="col" class="rounded-top-left-1 bg-primary ps-3 container-table-header noselect no-sort"></th>
@@ -57,28 +43,25 @@
5743
$containerHash = md5($containerName);
5844
$isDockwatch = isDockwatchContainer($container);
5945
$iconUrl = getIconByName($imageName, $containerName);
60-
$vulnCounts = $trivy->getVulnCounts($imageName);
61-
$scanCount = $trivy->getScanHistoryCount($imageName);
46+
$vulnCounts = $security->getVulnCounts($imageName);
47+
$scanCount = $security->getScanHistoryCount($imageName);
6248
$hasHistory = $scanCount > 1;
6349
?>
64-
<tr id="trivy-row-<?= $containerHash ?>" data-hash="<?= $containerHash ?>" data-image="<?= htmlspecialchars($imageName) ?>" data-name="<?= htmlspecialchars($containerName) ?>" data-has-history="<?= $hasHistory ? '1' : '0' ?>">
65-
<td class="container-table-row bg-secondary"><input type="checkbox" class="form-check-input trivy-check" onchange="toggleTrivyCheckAll()"></td>
50+
<tr id="security-row-<?= $containerHash ?>" data-hash="<?= $containerHash ?>" data-image="<?= htmlspecialchars($imageName) ?>" data-name="<?= htmlspecialchars($containerName) ?>" data-has-history="<?= $hasHistory ? '1' : '0' ?>">
51+
<td class="container-table-row bg-secondary"><input type="checkbox" class="form-check-input security-check" onchange="toggleSecurityCheckAll()"></td>
6652
<td class="container-table-row bg-secondary">
6753
<?php if ($iconUrl): ?>
6854
<img src="<?= htmlspecialchars($iconUrl) ?>" width="32" height="32" alt="" />
6955
<?php endif; ?>
7056
</td>
7157
<td class="container-table-row bg-secondary">
7258
<span class="container-name"><?= htmlspecialchars($containerName) ?></span>
73-
<?php if ($isDockwatch): ?>
74-
<i class="fas fa-download trivy-download-db" style="cursor: pointer;" title="Download DB" onclick="containerShell('<?= $containerName ?>', false, 'clear && <?= $downloadDbCmd ?> && <?= $downloadJavaDbCmd ?> && echo Finished downloading DB, exiting in 5s && sleep 5 && exit')"></i>
75-
<?php endif; ?>
7659
<br>
7760
<span class="text-muted small-text"><?= htmlspecialchars($imageName) ?></span>
7861
</td>
7962
<td class="container-table-row bg-secondary text-center">
8063
<?php if ($hasHistory): ?>
81-
<i class="fas fa-plus-square text-info trivy-expand" style="cursor: pointer;" onclick="toggleTrivyScans('<?= $containerHash ?>')"></i>
64+
<i class="fas fa-plus-square text-info security-expand" style="cursor: pointer;" onclick="toggleSecurityScans('<?= $containerHash ?>')"></i>
8265
<?php endif; ?>
8366
</td>
8467
<td class="container-table-row bg-secondary text-center" data-sort="<?= $vulnCounts['critical'] ?>">
@@ -118,18 +101,18 @@
118101
</td>
119102
<td class="container-table-row bg-secondary">
120103
<div class="btn-group btn-group-sm" role="group">
121-
<button type="button" class="btn btn-outline-light bg-secondary btn-sm" title="View Current Scan" onclick="viewTrivyScan('<?= $containerHash ?>', '<?= htmlspecialchars($imageName) ?>', 'current')"><i class="fas fa-eye fa-xs"></i></button>
122-
<button type="button" class="btn btn-outline-light bg-secondary btn-sm" title="View Scan History" onclick="viewTrivyScanHistory('<?= $containerHash ?>', '<?= htmlspecialchars($imageName) ?>')"><i class="fas fa-history fa-xs"></i></button>
123-
<button type="button" class="btn btn-outline-light bg-secondary btn-sm access-rw" title="Run Scan" onclick="runTrivyScan('<?= $containerHash ?>', '<?= htmlspecialchars($imageName) ?>', '<?= htmlspecialchars($containerName) ?>')"><i class="fas fa-shield-alt fa-xs"></i></button>
104+
<button type="button" class="btn btn-outline-light bg-secondary btn-sm" title="View Current Scan" onclick="viewSecurityScan('<?= $containerHash ?>', '<?= htmlspecialchars($imageName) ?>', 'current')"><i class="fas fa-eye fa-xs"></i></button>
105+
<button type="button" class="btn btn-outline-light bg-secondary btn-sm" title="View Scan History" onclick="viewSecurityScanHistory('<?= $containerHash ?>', '<?= htmlspecialchars($imageName) ?>')"><i class="fas fa-history fa-xs"></i></button>
106+
<button type="button" class="btn btn-outline-light bg-secondary btn-sm access-rw" title="Run Scan" onclick="runSecurityScan('<?= $containerHash ?>', '<?= htmlspecialchars($imageName) ?>', '<?= htmlspecialchars($containerName) ?>')"><i class="fas fa-shield-alt fa-xs"></i></button>
124107
</div>
125108
</td>
126109
</tr>
127110
<?php } ?>
128111
<tfoot>
129112
<tr>
130113
<td class="rounded-bottom-right-1 rounded-bottom-left-1 bg-primary ps-3" colspan="10">
131-
<button id="check-all-trivy-btn" class="dt-button mt-2 buttons-collection access-rw" tabindex="0" aria-controls="trivy-table" type="button"><input type="checkbox" class="form-check-input" onclick="toggleAllTrivy()" id="trivy-toggle-all"></button>
132-
<button id="trivy-scan-btn" class="dt-button mt-2 buttons-collection access-rw" tabindex="0" aria-controls="trivy-table" type="button" onclick="massApplyTrivyScan()">Scan Selected</button>
114+
<button id="check-all-security-btn" class="dt-button mt-2 buttons-collection access-rw" tabindex="0" aria-controls="security-table" type="button"><input type="checkbox" class="form-check-input" onclick="toggleAllSecurity()" id="security-toggle-all"></button>
115+
<button id="security-scan-btn" class="dt-button mt-2 buttons-collection access-rw" tabindex="0" aria-controls="security-table" type="button" onclick="massApplySecurityScan()">Scan Selected</button>
133116
</td>
134117
</tr>
135118
</tfoot>
@@ -142,26 +125,26 @@
142125
}
143126

144127
if ($_POST['m'] == 'getVulns') {
145-
$image = $_POST['image'] ?? '';
146-
$file = $_POST['file'] ?? null;
147-
$trivy = new Trivy();
148-
$vulns = $trivy->getVulns($image, $file);
128+
$image = $_POST['image'] ?? '';
129+
$file = $_POST['file'] ?? null;
130+
$security = new Security();
131+
$vulns = $security->getVulns($image, $file);
149132
echo json_encode($vulns ?? []);
150133
}
151134

152135
if ($_POST['m'] == 'getScanHistory') {
153-
$image = $_POST['image'] ?? '';
154-
$trivy = new Trivy();
155-
$history = $trivy->getScanHistory($image);
136+
$image = $_POST['image'] ?? '';
137+
$security = new Security();
138+
$history = $security->getScanHistory($image);
156139
echo json_encode($history);
157140
}
158141

159142
if ($_POST['m'] == 'getRecentScans') {
160-
$image = $_POST['image'] ?? '';
161-
$limit = intval($_POST['limit'] ?? 3);
162-
$trivy = new Trivy();
163-
$history = $trivy->getScanHistory($image);
164-
$recent = array_slice($history, 1, $limit);
143+
$image = $_POST['image'] ?? '';
144+
$limit = intval($_POST['limit'] ?? 3);
145+
$security = new Security();
146+
$history = $security->getScanHistory($image);
147+
$recent = array_slice($history, 1, $limit);
165148
echo json_encode($recent);
166149
}
167150

@@ -171,16 +154,16 @@
171154

172155
logger(UI_LOG, 'scanning image ' . $image . ' ->');
173156

174-
$trivy = new Trivy();
175-
$result = $trivy->scanImage($image);
157+
$security = new Security();
158+
$result = $security->scanImage($image, intval($settingsTable['securityScanner']), $settingsTable['securitySnykAPIKey']);
176159

177160
if (!empty($result)) {
178161
logger(UI_LOG, $result);
179162
}
180163

181164
logger(UI_LOG, 'scanning image ' . $image . ' <-');
182165

183-
$vulnCounts = $trivy->getVulnCounts($image);
166+
$vulnCounts = $security->getVulnCounts($image);
184167
echo json_encode([
185168
'success' => true,
186169
'result' => $result,

0 commit comments

Comments
 (0)