{{ title }}
in a finding description and it will be replaced by the report title when generating a report, without having to edit it manually.
Jinja has extensive documentation on their web site, which is a good starting point. For Word DOCX files, Ghostwriter uses the python-docx-template library which adds a few extensions.
{{ title }}
and the project title through {{ project.title }}
.
In addition, the rich text fields on a finding have an additional finding
variable, which is a copy of the object from the findings
array in the report.
{{p rich_text_variable}}
. This will replace the tag’s paragraph with the paragraphs in the rich text field. For example:
Report Additional Info: {{p extra_fields.additional_info}}
{%p for finding in findings %} {{finding.name}} {{p finding.description}} {%p endfor %}By specifying
p
on the for and endfor statements, the paragraphs they are in will be deleted, so that they don’t cause extra newlines in the document.
To generate a list in a DOCX template, use the p
prefix:
To generate a list in a rich text field, use the
- {%p for tag in tags %}
- {{tag}}
- {%p endfor %}
li
prefix:
To generate a table in a DOCX template or rich text field, use the
- {%li for tag in tags %}
- {{tag}}
- {%li endfor %}
tr
prefix:
Finding | Severity |
---|---|
{%tr for finding in findings %} | |
{{finding.name}} | {{finding.severity_rt}} |
{%tr endfor %} |
p
prefix, li
will replace the list element and tr
will replace the entire table row.
{{.evidence name}}
or {{mk_evidence("name")}}
: Inserts the evidence with the specified friendly name. Rich text fields on findings will search the finding’s evidence; others search through the report evidence. Also creates a Word bookmark.
{{.caption}}
, {{.caption name}}
or {{mk_caption("name")}}
: Creates a caption. If a name is specified, creates a Word bookmark with the specified name, which can also be referenced in {{.ref}}
below. Any text in the same paragraph will be added to the caption.
{{.ref name}}
or {{mk_ref("name")}}
: Makes a reference to a Word bookmark, usually generated by {{.evidence}}
or {{.caption}}
above. The text will go to the bookmark when ctrl+clicked.
{% for finding in findings|filter_severity(["Critical", "High"]) %}
: Filters findings by severity to those in the list.
{% for finding in findings|filter_type(["Network", "Web"]) %}
: Filters findings by type to those in the list.
{{text|strip_html}}
: Removes HTML tags from the text while adding newlines based on <p>
and <br>
tags.
{% for target in targets|compromised %}
: Filters targets by those marked as compromised.
{{ start_date|add_days(1) }}
: Adds an number of business days to the date.
{{ start_date|format_datetime("Ymd") }}
: Formats a date using Django date format strings.
{{ findings|get_item(0) }}
: Gets an item from a list or dictionary. Unlike foo.bar
in Jinja, this forcibly uses the Python indexing operator, so it will not conflict with attributes.
{{ title|regex_search("a-z+") }}
: Performs a regex search on a string, returning the match or None.
{% for finding in findings|filter_tags(["xss", "T1651"]) %}
: Filters objects to include only ones that have any of the tags in the list.
{{ "{{" }}
, {{ "{%" }}
, etc., to emit a string literal. This is convenient for one-off replacements.
For larger blocks, you can use Jinja’s {% raw %} ... {% endraw %}
blocks. Content in the block will not be parsed as Jinja tags and will be emitted as-is.