Skip to content

Instantly share code, notes, and snippets.

@dirsigler
Created October 8, 2024 07:31
Show Gist options
  • Save dirsigler/29326d1b5bf88beaec5598c2a5f1f7b1 to your computer and use it in GitHub Desktop.
Save dirsigler/29326d1b5bf88beaec5598c2a5f1f7b1 to your computer and use it in GitHub Desktop.
Trivy Template to support HTML reports for License scans
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
{{- if . }}
<style>
* {
font-family: Arial, Helvetica, sans-serif;
box-sizing: border-box;
}
h1 {
text-align: center;
}
.group-header th {
font-size: 200%;
}
.sub-header th {
font-size: 150%;
}
table {
width: 100%;
border-collapse: collapse;
margin: 0 auto;
table-layout: auto;
}
th, td {
border: 1px solid black;
padding: .3em;
text-align: left;
white-space: normal;
word-wrap: break-word;
}
.severity {
text-align: center;
font-weight: bold;
color: #fafafa;
}
.severity-LOW .severity { background-color: #5fbb31; }
.severity-MEDIUM .severity { background-color: #e9c600; }
.severity-HIGH .severity { background-color: #ff8800; }
.severity-CRITICAL .severity { background-color: #e40000; }
.severity-UNKNOWN .severity { background-color: #747474; }
.severity-LOW { background-color: #5fbb3160; }
.severity-MEDIUM { background-color: #e9c60060; }
.severity-HIGH { background-color: #ff880060; }
.severity-CRITICAL { background-color: #e4000060; }
.severity-UNKNOWN { background-color: #74747460; }
table tr td:first-of-type {
font-weight: bold;
}
.links a,
.links[data-more-links=on] a {
display: block;
word-wrap: break-word;
}
.links[data-more-links=off] a:nth-of-type(1n+5) {
display: none;
}
a.toggle-more-links { cursor: pointer; }
body {
overflow-x: hidden;
}
</style>
<title>{{- escapeXML ( index . 0 ).Target }} - Trivy Report - {{ now.Format "2006-01-02 15:04:05" }} </title>
<script>
window.onload = function() {
document.querySelectorAll('td.links').forEach(function(linkCell) {
var links = [].concat.apply([], linkCell.querySelectorAll('a'));
[].sort.apply(links, function(a, b) {
return a.href > b.href ? 1 : -1;
});
links.forEach(function(link, idx) {
if (links.length > 3 && 3 === idx) {
var toggleLink = document.createElement('a');
toggleLink.innerText = "Toggle more links";
toggleLink.href = "#toggleMore";
toggleLink.setAttribute("class", "toggle-more-links");
linkCell.appendChild(toggleLink);
}
linkCell.appendChild(link);
});
});
document.querySelectorAll('a.toggle-more-links').forEach(function(toggleLink) {
toggleLink.onclick = function() {
var expanded = toggleLink.parentElement.getAttribute("data-more-links");
toggleLink.parentElement.setAttribute("data-more-links", "on" === expanded ? "off" : "on");
return false;
};
});
};
</script>
</head>
<body>
<h1>{{- escapeXML ( index . 0 ).Target }} - Trivy Report - {{ now.Format "2006-01-02 15:04:05" }}</h1>
<table>
{{- range . }}
{{ $target := .Target }}
<!-- Vulnerabilities -->
{{- if (gt (len .Vulnerabilities) 0) }}
<tr class="group-header"><th colspan="7">{{ .Type | toString | escapeXML }}</th></tr>
<tr class="sub-header">
<th>Target/FilePath</th>
<th>Package</th>
<th>Vulnerability ID</th>
<th>Severity</th>
<th>Installed Version</th>
<th>Fixed Version</th>
<th>Links</th>
</tr>
{{- range .Vulnerabilities }}
<tr class="severity-{{ escapeXML .Vulnerability.Severity }}">
<td>{{ escapeXML $target }}</td>
<td class="pkg-name">{{ escapeXML .PkgName }}</td>
<td>{{ escapeXML .VulnerabilityID }}</td>
<td class="severity">{{ escapeXML .Vulnerability.Severity }}</td>
<td class="pkg-version">{{ escapeXML .InstalledVersion }}</td>
<td>{{ escapeXML .FixedVersion }}</td>
<td class="links" data-more-links="off">
{{- range .Vulnerability.References }}
<a href={{ escapeXML . | printf "%q" }}>{{ escapeXML . }}</a>
{{- end }}
</td>
</tr>
{{- end }}
{{- end }}
<!-- Misconfigurations -->
{{- if (gt (len .Misconfigurations) 0) }}
<tr class="group-header"><th colspan="6">Misconfigurations</th></tr>
<tr class="sub-header">
<th>Target/FilePath</th>
<th>Type</th>
<th>Misconf ID</th>
<th>Check</th>
<th>Severity</th>
<th>Message</th>
</tr>
{{- range .Misconfigurations }}
<tr class="severity-{{ escapeXML .Severity }}">
<td>{{ escapeXML $target }}</td>
<td class="misconf-type">{{ escapeXML .Type }}</td>
<td>{{ escapeXML .ID }}</td>
<td class="misconf-check">{{ escapeXML .Title }}</td>
<td class="severity">{{ escapeXML .Severity }}</td>
<td class="link" data-more-links="off" style="white-space:normal;">
{{ escapeXML .Message }}
<br>
<a href={{ escapeXML .PrimaryURL | printf "%q" }}>{{ escapeXML .PrimaryURL }}</a>
</br>
</td>
</tr>
{{- end }}
{{- end }}
<!-- License Scanning Results -->
{{- if (gt (len .Licenses) 0) }}
<tr class="group-header"><th colspan="7">License Scan Results</th></tr>
<tr class="sub-header">
<th>Target/FilePath</th>
<th>Package</th>
<th>License</th>
<th>Severity</th>
<th>Category</th>
<th>Confidence</th>
<th>Link</th>
</tr>
{{- range .Licenses }}
<tr class="severity-{{ escapeXML .Severity }}">
<td>{{ escapeXML $target }}</td>
<td class="pkg-name">{{ escapeXML .PkgName }}</td>
<td>{{ escapeXML .Name }}</td>
<td class="severity">{{ escapeXML .Severity }}</td>
<td>{{ escapeXML (.Category | toString) }}</td>
<td>{{ printf "%.2f" .Confidence }}</td>
<td class="links">
{{- if .Link }}
<a href={{ escapeXML .Link | printf "%q" }}>{{ escapeXML .Link }}</a>
{{- else }}
N/A
{{- end }}
</td>
</tr>
{{- end }}
{{- end }}
{{- end }}
</table>
{{- else }}
</head>
<body>
<h1>Trivy Returned Empty Report</h1>
{{- end }}
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment