Skip to main content

Custom templates

When generating a report featuring the results of your build rules check, you can use a custom template to define the information that is included and how that information is presented.

To do this, you will need to:

  1. Define your build rules;
  2. Compare your analysis results against your build rules and create a report of results using sl check-analysis. You'll pass the location of your custom template file to the sl check-analysis command.

Sample template

You can obtain a sample template by running sl check-analysis --v2 --dump-template:

{{ if .is_markdown }}{{ logo }}
{{ end }}
{{- title_begin -}}
Checking analysis of application {{ printf "%#q" .app }} against {{ .request.Rules | len }} build rules.
{{- title_end }}

{{ if .is_markdown }}Using `sl` version {{ .version }} ({{ .githash }}).

{{ end -}}

{{/* header above, body below */}}

{{- header_begin }}{{ if .request.IsDiff -}}
Checking new findings between {{ link_diff }}.
{{- else -}}
Checking findings on {{ link_single }}.
{{- end -}}{{ header_end }}
{{ if .request.Rules }}
Results per rule:{{"\n\n"}}
{{- range $rule := .request.Rules }}
{{- $ruleResult := index $.response.Rules $rule.ID -}}
{{bullet $ruleResult.Failed }}{{ $rule.ID }}: {{ if $ruleResult.Failed -}} {{"FAIL"|bold}} {{- else -}} pass {{- end }}
({{ $ruleResult.Matched }} matched {{ if eq $ruleResult.Matched 1 -}} vulnerability {{- else -}} vulnerabilities {{- end -}}
; configured threshold is {{ $rule.Threshold }}).{{"\n"}}
{{- if $ruleResult.Findings -}}
{{- if gt $ruleResult.Matched ($ruleResult.Findings|len) }}
First {{ if eq ($ruleResult.Findings|len) 1 }}{{ if $.request.IsDiff }}new {{end}}finding{{- else -}}
{{ $ruleResult.Findings|len }}{{ if $.request.IsDiff }} new{{end}} findings{{end}}:
{{- else if $.request.IsDiff }}
New {{ if eq ($ruleResult.Findings|len) 1 }}finding{{else}}findings{{end}}:
{{- else }}
{{ if eq ($ruleResult.Findings|len) 1 }}Finding{{else}}Findings{{end}}:
{{- end -}}{{"\n\n"}}
{{- if $ruleResult.HasCVEs -}}
{{- with $t := table " " ">ID" ">CVSS" ">Rating<" "CVE" "Title" -}}
{{- range $ruleResult.Findings -}}
{{- table_append $t (.ID|link_finding) (.CVSSScore|printf "%.1f") (.Last "cvss_31_severity_rating"|severity_rating_colorize) (.Last "cve") .Title -}}
{{- end -}}
{{- $t -}}
{{- end -}}
{{- else -}}
{{- with $t := table " " ">ID" ">CVSS" ">Rating<" "Title" -}}
{{- range $ruleResult.Findings -}}
{{- table_append $t (.ID|link_finding) (.CVSSScore|printf "%.1f") (.Last "cvss_31_severity_rating"|severity_rating_colorize) .Title -}}
{{- end -}}
{{- $t -}}
{{- end -}}
{{- end -}}{{- "\n" -}}
{{- summary " " (index $ruleResult.ByTag "cvss_31_severity_rating") "Severity rating" "critical" "high" "medium" "low" -}}
{{- summary " " (index $ruleResult.ByTag "finding_type") "Finding Type" -}}
{{- range $tag, $title := $.interesting -}}
{{- summary " " (index $ruleResult.ByTag $tag) $title -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end }}
{{- tail_urls }}
{{ if eq .num_failed 0 }}
All rules passed.
{{- else if .is_markdown }}
{{- if eq .num_failed 1 }}
1 rule failed.
{{- else }}
{{ .num_failed }} rules failed.
{{- end }}{{ end }}

Definitions

Custom templates use Go's text/template to display the following top-level data:

  • request: the scans check request object
  • response: the scans check response object
  • app: the application name (i.e., the name provided via the --app flag)
  • interesting: an associative array of tags to summarise if present in the findings
  • is_markdown: whether the template should be producing Markdown (as opposed to writing to the terminal)
  • version: the sl version
  • githash: the Git hash of sl
  • num_failed: the number of failed rules

In addition to the normal text/template functions, Qwiet provides the following functions:

  • summary: produces a summary table for the category if given an indent, an associative array of categories to counts (unsigned integers), a title, and an optional series of categories. If the series of categories is provided, then the table will have those, and only those, in the order given. Otherwise, the table will have all categories in the associative array, ordered descending by count, and then ordered by the category itself

  • table: returns a table that can then be added to using table_append and printed if given an indent and a series of headers. Headers are strings

    • If a header begins with > (greater-than) and ends with < (less-than), the column in the table is centered

    • If the header begins with > (greater-than), the column will be aligned to the right. Otherwise the column will be aligned to the left

    These alignment markers are removed from the actual header used. Additionally, the table will limit its width, if possible, to not exceed that of the terminal (or 200 characters for Markdown output)

  • table_append: appends a series of values to a table. There must be the same number of values as there were headers

  • table_print: prints a table; note that you can also print a table directly (e.g., {{ $t }} and {{ $t | table_print }} produce the same output)

  • link_finding: returns the link to the Qwiet Dashboard for this finding in this application if given a finding ID. When printing to the terminal, this will return a string that uses an ANSI (OSC 8) escape sequence directly. Otherwise, when outputting Markdown, it will return a bracketed label and add the URL to the output of tail_urls

  • link_single: returns the link to the Dashboard view for a single scan looking at the target scan. When printing to the terminal, this will return a string that uses an ANSI (OSC 8) escape sequence directly. Otherwise, when outputting Markdown, it will return a bracketed label and add the URL to the output of tail_urls

  • link_diff: returns the link to the dashboard view for a scan comparison between the source scan and the target scan. When printing to the terminal, this will return a string that uses an ANSI (OSC 8) escape sequence directly; otherwise, when outputting Markdown, it will return a bracketed label, and add the URL to the output of tail_urls

  • tail_urls: outputs the Markdown needed to convert the bracketed labels produced by the different link_* functions into hyperlinks. Does nothing when printing to the terminal

  • severity_colorize: produces a string that uses ANSI (SGR) escape sequence to colorize a given severity when printing to the terminal. Does nothing when outputting to Markdown

  • header_begin: returns the string needed to start a header. In the default template the header comes

  • header_end: returns the string that's needed to end a header

  • bullet: returns a bullet given a success/failure Boolean. When printing to the terminal, it will use different characters for success and for failure. Does nothing when outputting to Markdown.

  • bold: returns a string to make the given text bold

  • title_begin: returns the string that's needed to start a title

  • title_end: returns the string that's needed to end a title

  • logo: includes Qwiet's logo in the Markdown output

  • json: takes a single input and serializes it to JSON

If the template contains the string {{/* header above, body below */}} the template will be split in two with this string as the breaking point. The first template is evaluated and executed before the request is performed, and the second template is evaluated and executed after the server responds.