Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: HTML report #130

Closed
wants to merge 3 commits into from
Closed

feat: HTML report #130

wants to merge 3 commits into from

Conversation

tcdsv
Copy link
Contributor

@tcdsv tcdsv commented Jul 6, 2023

Closes #126

first version of HTML report.

  • updated format validation and commands description in main.go
  • created html.go report file and related templates

the output of the report: https://gist.github.com/tcdsv/764dd9db5d03ca08087694cfce0a214a
The report still needs some work on how it looks and what should be in it.

Limitations associated with the Report struct

  • It's not easy to include the source in the summary, as the first item in the map of Secrets needs to be retrieved in order to check its Source attribute.

  • The design of the Report struct, which organizes secrets based on filenames, makes it nontrivial to generate a report with multiple sources where secrets are grouped by source type. This suggests that for supporting reports with multiple sources, a possible mapping order in Report struct could be sources -> filenames -> secrets.

  • What I'm trying to clarify is whether the concept of the "Report" supports multiple sources or if it is designed to have only one source.

  • The Report struct lacks information such as version, time started, and time ended, which cannot be included in the summary. the Config struct has attributes like Name and Version, which are closely related to the Report struct. It makes sense to have them all together in the Report struct itself.

I submit this contribution under the Apache-2.0 license.

@baruchiro
Copy link
Contributor

Hi @tcdsv, I'm not reviewing it because it is a draft. Please let me know if you want me to review it.

@tcdsv tcdsv marked this pull request as ready for review July 9, 2023 12:42
@baruchiro baruchiro self-requested a review July 10, 2023 10:40
@baruchiro baruchiro assigned baruchiro and tcdsv and unassigned baruchiro Jul 10, 2023
Copy link
Contributor

@baruchiro baruchiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work, of course, more work is needed here.

  • @jossef, do we need to ask a designer to look at the HTML output?
  • Regarding reports from multiple sources, it is not supported right now. Of course, it might be supported in the future, but you shouldn't implement it right now.

It's not easy to include the source in the summary, as the first item in the map of Secrets needs to be retrieved in order to check its Source attribute.

I don't understand.


The design of the Report struct, which organizes secrets based on filenames, makes it nontrivial to generate a report with multiple sources where secrets are grouped by source type. This suggests that for supporting reports with multiple sources, a possible mapping order in Report struct could be sources -> filenames -> secrets.

I agree that the structure is nontrivial, but please consider we are not supporting multiple sources, are you still see a problem with this structure?


The Report struct lacks information such as version, time started, and time ended, which cannot be included in the summary. the Config struct has attributes like Name and Version, which are closely related to the Report struct. It makes sense to have them all together in the Report struct itself.

I see why the version and the time and so should be part of the report. But we can do it outside this PR to keep this PR focuses.

You're welcome to open an issue with more fields you think are needed, and we will review it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

We need to break the line (overflow-wrap: anywhere)
Also, I think putting it inside a code block will help.

var buffer bytes.Buffer
err := tmpl.Execute(&buffer, report)
if err != nil {
log.Fatalf("failed to create HTML report with error: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think maybe use log.Errorf, because Fatalf is calling os.Exit, and maybe there are more outputs formats that still can be written.

func getFuncMap() template.FuncMap {
return template.FuncMap{
"includeCSS": func() template.CSS { return template.CSS(cssTemplate) },
"includeSVG": func() template.HTML { return template.HTML(githubSVG) },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"includeSVG": func() template.HTML { return template.HTML(githubSVG) },
"includeGithubSVG": func() template.HTML { return template.HTML(githubSVG) },

Comment on lines +31 to +37
func getFuncMap() template.FuncMap {
return template.FuncMap{
"includeCSS": func() template.CSS { return template.CSS(cssTemplate) },
"includeSVG": func() template.HTML { return template.HTML(githubSVG) },
"includeLogo": func() template.HTML { return template.HTML(checkmarxLogo) },
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be declared as var instead of function:

Suggested change
func getFuncMap() template.FuncMap {
return template.FuncMap{
"includeCSS": func() template.CSS { return template.CSS(cssTemplate) },
"includeSVG": func() template.HTML { return template.HTML(githubSVG) },
"includeLogo": func() template.HTML { return template.HTML(checkmarxLogo) },
}
}
var funcMap = template.FuncMap{
"includeCSS": func() template.CSS { return template.CSS(cssTemplate) },
"includeSVG": func() template.HTML { return template.HTML(githubSVG) },
"includeLogo": func() template.HTML { return template.HTML(checkmarxLogo) },
}

)

func writeHtml(report Report) string {
tmpl := template.Must(template.New("report").Funcs(getFuncMap()).Parse(htmlTemplate))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is new for me.

When the template.New("report").Funcs(funcMap).Parse(htmlTemplate) returns (*template.Template, error), the template.Must that accept *template.Template, error will get the multi-var return value?
Good to know!


<div class="secret-info-details">
<span><strong>ID:</strong> {{ .ID }}</span>
<span><strong>Source:</strong> {{ .Source }}</span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the times, the Source will be a link, but not for Git, for example.

Do you think we can make it a link when it is?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking into it

@tcdsv
Copy link
Contributor Author

tcdsv commented Jul 11, 2023

It's not easy to include the source in the summary, as the first item in the map of Secrets needs to be retrieved in order to check its Source attribute.

I don't understand.

What I meant is that Report struct should have a Type field that indicates whether it is git/filesystem/etc... report. I wanted the the page to display a title that states the report type, for example, "Type: <report_type>, Number of items scanned: ...."

as you mentioned it is out of the scope of this PR

@baruchiro
Copy link
Contributor

@tcdsv We are working with our Product Manager to define the requirements here.

return template.FuncMap{
"includeCSS": func() template.CSS { return template.CSS(cssTemplate) },
"includeSVG": func() template.HTML { return template.HTML(githubSVG) },
"includeLogo": func() template.HTML { return template.HTML(checkmarxLogo) },

Check failure

Code scanning / gosec

The used method does not auto-escape HTML. This can potentially lead to 'Cross-site Scripting' vulnerabilities, in case the attacker controls the input.

The used method does not auto-escape HTML. This can potentially lead to 'Cross-site Scripting' vulnerabilities, in case the attacker controls the input.
func getFuncMap() template.FuncMap {
return template.FuncMap{
"includeCSS": func() template.CSS { return template.CSS(cssTemplate) },
"includeSVG": func() template.HTML { return template.HTML(githubSVG) },

Check failure

Code scanning / gosec

The used method does not auto-escape HTML. This can potentially lead to 'Cross-site Scripting' vulnerabilities, in case the attacker controls the input.

The used method does not auto-escape HTML. This can potentially lead to 'Cross-site Scripting' vulnerabilities, in case the attacker controls the input.
@baruchiro
Copy link
Contributor

Hi @tcdsv, just want to update you that we are still working on the HTML output definition, and soon we will return back to you.

Now when a product manager starts to look closely at this product, the HTML output exposes more out-of-scope questions, and I hope that when we finish to define the requirements for the HTML, we will get more things to improve.

@baruchiro
Copy link
Contributor

Status:

  1. Waiting for UI/UX team for a simple design
  2. @baruchiro will check a SARIF viewer maybe we can just print a SARIF viewer. Need to check Confluence location on SARIF output is not right #159

@baruchiro
Copy link
Contributor

Sorry, closing it, I see it is not important for us now :-(

@baruchiro baruchiro closed this Sep 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add HTML output option
2 participants