Helpers
Software Risk Manager includes all the #if, #unless, #each, and #with helpers provided by Handlebars. Several other helpers are also provided to assist as well.
formatDate
The formatDate
helper allows you to format a date by specifying a
format string. For example:
{{formatDate finding.firstSeenOnDate 'YYYY-MM-DD'}}
will take the first-seen date for the finding and convert it into an ISO-8601 valid format. You can use the symbols below to create your format string:
M
month: 1, 2, 11, etc.MM
month: 01, 02, etc.MMM
month: Jan, Feb, etc.MMMM
full month nameD
day of month: 1, 2, 11, etc.DD
day of month: 01, 02, 11, etc.ddd
day of week: Sun, Mon, etc.dddd
day of week: Sunday, Monday, etc.YY
year: 98, 99, 00, 01, etc.YYYY
year: 1998, 1999, 2000, 2001, etc.
The formatDate
helper uses Moment.js under the hood, so you can look
at its documentation for more formatting symbols.
makeOxfordList
The makeOxfordList
helper assists in generating an Oxford list from
an array of elements. The body will be evaluated for every item in the list.
For example, to list all of the Software Risk Manager Finding IDs, the template
{{#makeOxfordList allFindings ',' 'and'}}{{this.id}}{{/makeOxfordList}}
will result in
39955, 39956, 39939, and 39940
when evaluated on a group of findings with the IDs 39955, 39956, 39939, and 39940.
formatLocation
The formatLocation
helper formats a location object into a
user-readable version similar to those displayed elsewhere in Software Risk
Manager.
For example, the template
{{formatLocation finding.location}}
will result in
AbstractLesson.java:182
when evaluated on a finding located in
WEB-INF/classes/org/owasp/webgoat/lessons/AbstractLesson.java
on line 182 (columns 25-50).
By default, the short name of the location is used, and any column numbers are
omitted. You may opt to show the complete location information by passing
true
as the second parameter to this helper. For example, the
template
{{formatLocation finding.location true}}
will result in
WEB-INF/classes/org/owasp/webgoat/lessons/AbstractLesson.java:182:25-50
in the previous example.
formatCWE
The formatCWE
helper creates a more informative representation of a
finding's CWE (if one is available).
The true/false parameter determines if a link to MITRE will be available. The
trackerType
parameter will default to the issue tracker type
currently being processed.
For example,
{{formatCWE finding.cwe true trackerType}}
will result in
CWE 78 - Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') ([MITRE|https://cwe.mitre.org/data/definitions/78.html])
when evaluated on a finding associated with CWE-78.
If the second argument provided is true, a MITRE link for the CWE will be included (formatted properly for the issue tracker being used).
If no CWE is present on the finding, this helper will evaluate to an empty string if the second argument is false, or to "No Common Weakness Enumeration information available" if the second argument is true.
stripHtmlMarkup
The stripHtmlMarkup
helper takes an HTML string and returns a copy
with all HTML tags removed, with newlines/spaces inserted as necessary while
attempting to preserve native formatting. By default, HTML escape sequences will be
converted in the result; use false
for the second parameter (as
seen below) instead to prevent this. Whitespace-equivalent escape sequences (e.g.,
) will simply be replaced with a space regardless of
the second parameter value.
<h1>Explanation</h1>
<p>
Cross-site scripting vulnerabilities occur when:
<ol>
<li>Data enters through an untrusted source</li>
<li>The data is included in dynamic content without being validated for malicious code</li>
</ol>
</p>
{{{stripHtmlMarkup finding.descriptions.general.content true}}}
Explanation
Cross-site scripting vulnerabilities occur when:
- Data enters through an untrusted source
- The data is included in dynamic content without being validated for malicious code
The following are known issues and limitations:
- Ordered/unordered lists will produce the same
-
prefix on list items. - Nested lists may be improperly formatted.
- Issue trackers that interpret plaintext as emojis (e.g.,
:(
) (e.g., Jira) will still interpret as emojis. - The un-escaped HTML content may be re-converted to the escape sequences
automatically by Handlebars. (e.g., HTML content with
&
is un-escaped to&
bystripHtmlMarkup
, but gets converted back to&
in the output by Handlebars.) Use{{{}}}
instead of{{}}
to prevent this behavior.
makeMarkupFromHtml
The makeMarkupFromHtml
helper takes an HTML string and reformats it
into appropriate markup for the current issue tracker. The helper uses the following
formats:
- Jira. Atlassian Wiki markup format.
- Azure DevOps. No processing/pass-through (HTML content supported by ADO).
- ServiceNow. Simple text extraction, acts as an alias for
stripHtmlMarkup
with unescaping enabled. - GitLab. Markdown.
The helper takes three arguments: the first is required and the following two are
optional: the HTML to convert and the name of the issue tracker type to target (use
trackerType
if not manually overriding; accepted values are
jira
, azure
, servicenow
, and
gitlab
), and a boolean flag
(true
/false
), indicating whether to pre-clean
the HTML of any non-textual elements (defaults to false
). The
pre-cleaning flag is usually not necessary, but if there are formatting issues, the
pre-cleaning option may prevent these issues.
For example, a finding with a description of
<h1>Explanation</h1>
<p>
Cross-site scripting vulnerabilities occur when:
<ol>
<li>Data enters through an untrusted source</li>
</ol>
</p>
and a template with
{{{makeMarkupFromHtml finding.descriptions.general.content trackerType}}}
will approximately result in
(If configured tracker is Jira or using `jira` as the second argument value)
h1. Explanation
Cross-site scripting vulnerabilities occur when:
# Data enters through an untrusted source
(If configured tracker is Azure DevOps or using `azure` as the second argument value)
<h1>Explanation</h1><p>Cross-site scripting vulnerabilities occur when: <ol><li>Data enters through an untrusted source</li></ol></p>
(If configured tracker is ServiceNow, or using `servicenow` as the second argument value)
Explanation
Cross-site scripting vulnerabilities occur when:
- Data enters through an untrusted source
(If configured tracker is GitLab, or using `gitlab` as the second argument value)
# Explanation
Cross-site scripting vulnerabilities occur when:
1. Data enters through an untrusted source
Keep in mind that the use of {{}}
vs {{{}}}
will
affect how Handlebars escapes any HTML-like content—typically, the
{{{}}}
literal format is appropriate.
The following are known issues and limitations:
- Jira/Atlassian conversion ignores
<pre>
code blocks (limitation of Atlassian Renderer). - Super/sub-scripts are generally unsupported (Jira/Atlassian renderer supports it but has known bugs).
- Nested lists in any format may be improperly formatted.
- Issue trackers that interpret plaintext as emojis (e.g.,
:(
) (e.g., Jira) will still interpret as emojis. - Issue trackers whose formatting is whitespace-sensitive (i.e., Jira, GitLab)
may have formatting issues due to trailing/leading whitespace (the use of
~
for whitespace control is recommended).
makeSource Snippet
The makeSourceSnippet
helper takes the
finding.sourceSnippet
object and outputs a formatted source
snippet.
{{makeSourceSnippet finding.sourceSnippet}}
function foo() {
console.log('bar');
}
- Jira/Atlassian shows line numbers, but by default do not support configuring the line numbers. The line numbers will start at 1.
- Jira/Atlassian has an issue with preserving the first source line's level of indentation.
- GitLab, Azure, and ServiceNow do not show line numbers.
- Service now only supports code blocks in specific fields, like the
Additional Comments
field.
minBy and maxBy
The minBy
and maxBy
helpers will cause the provided
expression body to be evaluated against the object with the lowest or highest value.
The path to this value is provided as an argument.
{{#minBy allFindings "severity.key"}}
The lowest severity is on finding {{id}} with severity of {{severity.name}}.
{{/minBy}}
The lowest severity is on finding 10 with severity of Info.
when evaluated on a group of findings, where the lowest severity finding has the ID of 10 and severity of info.
In the case of a tie (e.g., multiple findings or results with the minimum or maximum value), the first item with that value will be used. As outlined in Finding Objects, in the case of a tie, this will give the finding or result with the highest severity and lowest numeric ID.
Nested Arrays
These helpers can also handle nested arrays in a more advanced use case. This is
signified by adding a .[]
at any point the helper should continue
iterating over inner arrays. The expression body's context will be at the inner-most
object, and the parent object(s) may be referenced if desired.
{{#maxBy allFindings "results.[].severity.key"}}
Finding {{../../id}}, Result {{descriptor.name}}, Severity {{severity.name}}
{{/maxBy}}
Finding 10, Result My Weakness, Severity Medium
{{#maxBy allFindings "results.[].metadata.cvssV3"}}{{metadata.cvssV3}}{{/maxBy}}
9.8
when evaluated against a group of findings where the highest CVSS V3 metadata entry on any of the findings' results is 9.8.
Notice that the finding ID is accessed using {{../../id}}
. You may
have been expecting {{../id}}
to fetch the finding ID, since the
finding is the parent of the result that was selected. However, the array of results
itself is the immediate parent, and the parent of that is the finding, so
../..
is used.