Templating and Rich Text Fields

DOCX templates uploaded to Ghostwriter and rich text fields in Ghostwriter are both processed with Jinja 2, which will replace text from the document with data from the report. For example, you can write {{ 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.


All templates have access to the report data. To view what that includes, select the "Generate exportable JSON" option from the Generate Report page. For example, the report title is available as {{ 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.


Ghostwriter provides the following extensions in rich text fields:

  • {{.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 amount of business days to the date.

  • {{ start_date|format_datetime("Ymd") }}: Formats a date according to a PHP-style format string.

  • {{ 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.

Last updated