diff --git a/community_images/common/templates/image_readme.j2 b/community_images/common/templates/image_readme.j2
index ccd4bf4a02..90b2e573aa 100644
--- a/community_images/common/templates/image_readme.j2
+++ b/community_images/common/templates/image_readme.j2
@@ -1,6 +1,4 @@
-
-
-
+[![RapidFort][rapidfort-logo-header-svg]][rapidfort-logo-header-link]
@@ -10,9 +8,8 @@
[![Slack][slack-badge]][slack-link]
[![FOSSA Status][fossa-badge]][fossa-link]
-
-
-
+
+[![Zero cve images][zero-cve-images-svg]][zero-cve-images-link]
@@ -26,22 +23,12 @@ RapidFort has optimized and hardened this {{ official_name }} container image. T
This optimized image is functionally equivalent to [{{- source_image_provider }} {{ official_name -}}][source-image-repo-link] image but more secure with a significantly smaller software attack surface.
-
-
-
-
-
+[![Vulnerabilities by severity][vulns-chart-svg]][vulns-chart-link]
+[![Original vs. this image][savings-svg]][savings-link]
-
-
-
-
-
+[![View Report][full-report-svg]][full-report-link]
-
-
-
@@ -77,9 +64,7 @@ docker run -e RF_ACCESS_TOKEN="your_access_token" image_name
The runtime instructions for this hardened container image are the same as the official release. Follow the instructions provided with the [{{- source_image_provider }} {{ official_name -}}][source-image-repo-link].
-
-
-
+[![View Detailed Instructions][instructions-svg]][instructions-link]
@@ -97,9 +82,8 @@ RapidFort is the pioneering Software Attack Surface Management (SASM) platform i
Vulnerability reports for RapidFort's hardened images are updated daily to include newly discovered vulnerabilities and fixes.
-
-
-
+
+[![View on GitHub][view-github-svg]][view-github-link]
@@ -118,9 +102,7 @@ We are big fans of open-source software and secure software development. RapidFo
Join our slack community for any questions.
-
-
-
+[![RapidFort Community Slack][slack-png]][slack-link]
## 🌟 Support this project
@@ -140,6 +122,9 @@ Learn more about RapidFort's pioneering Software Attack Surface Management platf
+[rapidfort-logo-header-link]: {{ report_url -}}?utm_source=github&utm_medium=ci_view_report&utm_campaign=sep_01_sprint&utm_term={{- name -}}&utm_content=rapidfort_logo
+[rapidfort-logo-header-svg]: https://raw.githubusercontent.com/rapidfort/community-images/main/contrib/logo_light.svg
+
[dh-rf-badge]: https://img.shields.io/badge/dockerhub-images-important.svg?logo=Docker
@@ -169,4 +154,27 @@ Learn more about RapidFort's pioneering Software Attack Surface Management platf
[source-image-repo-link]: {{ source_image_repo_link }}
[rf-dh-image-link]: https://hub.docker.com/r/{{- rf_docker_link }}
-[savings-link]: https://github.com/rapidfort/community-images/raw/main/community_images/ {{- github_location -}} /assets/savings.svg
+
+
+[savings-svg]: https://github.com/rapidfort/community-images/raw/main/community_images/ {{- github_location -}} /assets/savings.svg
+[savings-link]: {{ report_url -}}?utm_source=github&utm_medium=ci_view_report&utm_campaign=sep_01_sprint&utm_term={{- name -}}&utm_content=image_savings_link
+
+[vulns-chart-svg]: https://github.com/rapidfort/community-images/raw/main/community_images/ {{- github_location -}} /assets/vulns_charts.svg
+[vulns-chart-link]: {{ report_url -}}?utm_source=github&utm_medium=ci_view_report&utm_campaign=sep_01_sprint&utm_term={{- name -}}&utm_content=vulns_charts
+
+[full-report-svg]: https://raw.githubusercontent.com/rapidfort/community-images/main/contrib/full_report.svg
+[full-report-link]: {{ report_url -}}?utm_source=github&utm_medium=ci_view_report&utm_campaign=sep_01_sprint&utm_term={{- name -}}&utm_content=get_full_report_button
+
+[instructions-link]: {{- source_image_readme -}}
+[instructions-svg]: https://raw.githubusercontent.com/rapidfort/community-images/main/contrib/view_details.svg
+
+
+[zero-cve-images-link]: https://hub.rapidfort.com/repositories?utm_source=github&utm_medium=ci_view_report&utm_campaign=sep_01_sprint&utm_term={{- name -}}&utm_content=zero_vulns_cve
+[zero-cve-images-svg]: https://raw.githubusercontent.com/rapidfort/community-images/main/contrib/zero_cve_images_link.svg
+
+[slack-link]: https://join.slack.com/t/rapidfortcommunity/shared_invite/zt-1g3wy28lv-DaeGexTQ5IjfpbmYW7Rm_Q
+[slack-png]: https://raw.githubusercontent.com/rapidfort/community-images/main/contrib/github_banner.png
+
+[view-github-link]: https://github.com/rapidfort/community-images/tree/main/community_images/{{- github_location -}}
+[view-github-svg]: https://raw.githubusercontent.com/rapidfort/community-images/main/contrib/view_github.svg
+
diff --git a/contrib/github_banner.png b/contrib/github_banner.png
index d0e1089af6..44d1037cf9 100644
Binary files a/contrib/github_banner.png and b/contrib/github_banner.png differ
diff --git a/report_shots/shots.js b/report_shots/shots.js
index b9e0a7dd70..6b25ad5581 100644
--- a/report_shots/shots.js
+++ b/report_shots/shots.js
@@ -72,7 +72,7 @@ const generateCharts = async (imageName, platform, imageSavePath) => {
// const sizeSavingsChartSVG = await generateSavingsChart('Attack surface', imageInfo.origImageSize, imageInfo.hardenedImageSize, true);
// const contextualSeverityChart = await generateContextualSeverityChart(vulnsOriginalSummary)
// const vulnsBySeverityChart = await generateVulnsBySeverityChart(vulnsOriginalSummary.default, vulnsHardenedSummary.default);
- const {width, svg:vulnsCountChartSVG} = await generateVulnsCountChart(vulnsOriginalSummary.default);
+ const {width, svg:vulnsCountChartSVG} = await generateVulnsCountChart(vulnsHardenedSummary.default);
const vulnsOriginalHardenedChartSVG = await generateVulnsOriginalHardenedChart(width, vulnsOriginalSummary.default, vulnsHardenedSummary.default);
@@ -716,6 +716,13 @@ async function generateSavingsCardsCompound(savingsData) {
// return back SVG as string
});
+
+ // Adjust the width to 760px and set the height proportionally
+ draw.width(760); // Set the width to 760px
+ const { width, height } = draw.viewbox(); // Get original dimensions from viewBox
+ const newHeight = (760 / width) * height; // Scale height proportionally
+ draw.size(760, newHeight); // Set the new size on the SVG
+
return draw.svg();
}
@@ -724,53 +731,59 @@ async function mergeSvgHorizontally(svgStrings, gap) {
const { SVG, registerWindow } = await import('@svgdotjs/svg.js');
const { createSVGWindow } = await import('svgdom');
const window = createSVGWindow();
- const document = window.document;
- registerWindow(window, document);
-
- const remainingCSSList = []
- const canvas = SVG(document.documentElement);
- const uniqueCSSRules = new Set();
- let totalWidth = 0;
- let maxHeight = 0;
- let fontFaceCaptured = false; // Track if font-face has already been captured
-
- svgStrings.forEach((svgString, index) => {
- // Extract all styles content
- const styleMatch = svgString.match(/`;
+ if (index > 0) totalWidth += gap;
+ svg.move(totalWidth, 0); // Move each SVG horizontally with the specified gap
+ totalWidth += width;
+ maxHeight = Math.max(maxHeight, height);
+
+ canvas.add(svg);
+ });
+
+ // Construct the final style tag with unique rules
+ const combinedStyle = ``;
+
+ // Add the combined styles to the canvas
+ canvas.svg(combinedStyle + canvas.svg());
- // Add the combined styles to the canvas and set the final canvas size
- canvas.svg(combinedStyle + canvas.svg());
- canvas.size(totalWidth, maxHeight);
+ // Set the viewBox to scale down the combined SVG to a width of 760px
+ const scaleFactor = 760 / totalWidth;
+ const scaledHeight = maxHeight * scaleFactor;
+ canvas.viewbox(0, 0, totalWidth, maxHeight); // Set the viewBox based on the combined content size
+ canvas.size(760, scaledHeight); // Set the final scaled width and proportional height
- return canvas.svg();
+ return canvas.svg();
}
async function main() {
const imgListPath = process.argv[2]
@@ -778,6 +791,7 @@ async function main() {
const imgList = await fsPromise.readFile(imgListPath, { encoding: 'utf8' });
const imgListArray = imgList.split("\n");
+ // const imgListArray = ['apache/bitnami'];
for await (const imagePath of imgListArray) {