Tips & Tricks
Top-level (root) tags can be used anywhere in your report template.
Examples of these tags include:
- {projectName}
- {#vulnerabilities}
- {#attackchains}
- {#assets}
Top-level (root) tags are distinguished by having 0 indentation (furthest to the left) in the section Available Tags for Individual Reports
If the tag starts with a hashtag {#..} then it is a list/array therefore you must add a closing tag {/}. For example {#vulnerabilities}...{/}
Nested tags can be accessed from any of the top-level (root) tags.
Examples of nested tags:
- {#vulnerabilities} --> {title}
- {#vulnerabilities} --> {priority}
- {#vulnerabilities} --> {#affected_assets} -->{asset}
Nested tags are distinguished by having an indentation of 1 more in the section Available Tags for Individual Reports
Nested tags often contain details for the parent tag. For example, {title} contains the title for each vulnerability when used within {#vulnerabilities}.
In AttackForge when you create a vulnerability on a project, you start by selecting a vulnerability template/write-up from your library, then you link it to the affected asset(s) or scope on your project.
The same hierarchical structure applies in ReportGen. You start by first looping through your vulnerabilities e.g. {#vulnerabilities} then access their affected assets e.g. {#affected_assets}. There is a 'one-to-many' relationship between vulnerabilities and affected assets.
Vulnerabilities in ReportGen are unique i.e. there is only 1 vulnerability for each template/write-up from your library. The affected assets are then linked to these vulnerabilities. This helps to cut your reporting size down by focusing on 'unique' vulnerabilities only.
To loop through vulnerabilities in your report and print the title and priority for each vulnerability, you would include the following in your template:
{#vulnerabilities}
{priority} - {title}
{/}
If you then wanted to also include the name of each affected asset on your vulnerability, you would include the following in your template:
{#vulnerabilities}
{priority} - {title}
{#affected_assets}
{asset}
{/}{/}
!IMPORTANT: Every time you open a loop using hashtag {#..} you must ensure to close that loop, otherwise you will get parser errors.
ReportGen automatically includes the parents for each object in your JSON project/reporting file. This means you can traverse up or down anywhere in the report, to access the right data you need.
For example, say you were looping through each vulnerability and you wanted to print the project name as well as the vulnerability title - you could do the following:
{#vulnerabilities}
{parent.projectName} – {title}
{/}
Now instead if you are looping through affected assets and you want to print the project name + vulnerability title + affected asset name - you could do the following:
{#vulnerabilities}
{#affected_assets}
{parent.parent.projectName} – {parent.title} – {asset}
{/}{/}
If you are unsure of what data or parents are available to you at anywhere in your report, you can use help function:
{#vulnerabilities}
{#affected_assets}
{$help["%()"]}
{/}{/}
This will print a help section in your browser console when you try to run the report, which will detail all data you can access, including any parents, at that time and section within your template.

{$help["%()"]}
Use this procedure to print diagnostic information to your ReportGen browser console, to help you with understanding what scope (tags/keys) is available. This helps you to access that correct data you need in your report.
Insert this tag in the relevant section in your template where you want to see what data is available to you, and how to access it.
This example will show you what data is available to you in each loop iteration.
{#vulnerabilities}
{#affected_assets}
{$help["%()"]}
{/}{/}

You can create IF conditions in your template by inserting a hashtag and immediately proceeding with the condition i.e. {#... == "..."}
An example is included below to only print vulnerabilities in the report which have a critical priority:
{#vulnerabilities}
{#priority == "Critical"}
Critical Vulnerability: {title}
{/}{/}
You can create IF AND conditions in your template by inserting a hashtag and immediately proceeding with the condition i.e. {#... == "..." && ... == "..."}
An example is included below to only print vulnerabilities in the report which have a critical priority and title is SQL Injection:
{#vulnerabilities}
{#priority == "Critical" && title == "SQL Injection"}
Critical Vulnerability: SQL Injection
{/}{/}
You can create IF OR conditions in your template by inserting a hashtag and immediately proceeding with the condition i.e. {#... == "..." || ... == "..."}
An example is included below to only print vulnerabilities in the report which have a critical or high priority:
{#vulnerabilities}
{#priority == "Critical" || priority == "High"}
{priority} - {title}
{/}{/}
You can create IF ELSE conditions in your template by inserting a hashtag and immediately proceeding with the condition i.e. {#... == "..."} and then after the closing tag {/} you can insert your else statement {^...}...{/}
An example is included below to print each project note if they exist, or to indicate that no project notes were found:
{#projectNotes}
{note}
{/}
{^projectNotes}
No project notes found.
{/}
Using the example above, the report will either print the details for each project note; or it will print No project notes found.
Conditional sections can help you to create sections within your report which are printed only if the condition(s) have been met.
For example:
{#projectNotes[0]}
PROJECT NOTES
{/}
{#projectNotes}
{note}
{/}
{^projectNotes}
There are no project notes.
{/}
Because {#projectNotes} is an array (list) of notes, we can use the condition {#projectNotes[0]} which only runs the loop on the first entry [0] or note in the list, assuming that there is at least one note in the list. Therefore using the example above, if there is at least one project note - the section title PROJECT NOTES will be printed.
For example, lets say you want to
- count every vulnerability instance (affected asset);
- count every vulnerability instance (affected asset) which is Open/Not Fixed AND Not Informational
- count every vulnerability instance (affected asset) which is Ready For Retest AND Not Informational
- count every vulnerability instance (affected asset) which is Closed/Fixed AND Not Informational
You can achieve this using the following:
{$declare[TotalVulnerabilities][0]}
{$declare[TotalFixedVulnsExInfo][0]}
{$declare[TotalRetestVulnsExInfo][0]}
{$declare[TotalNotFixedVulnsExInfo][0]}
{#vulnerabilities}
{#affected_assets}
{$increment[TotalVulnerabilities][1]}
{#remediation_status | includes:[“Open”]}
{#priority !== “Info”}
{$increment[TotalNotFixedVulnsExInfo][1]}
{/}{/}
{#remediation_status | includes:[“Ready for Retest”]}
{#priority !== “Info”}
{$increment[TotalRetestVulnsExInfo][1]}{/}{/}
{#remediation_status | includes:[“Closed”]}
{#priority !== “Info”}
{$increment[TotalFixedVulnsExInfo][1]}{/}{/}
{/affected_assets}
{/vulnerabilities}
Total Vulnerabilities for All Affected Assets:
{$value[TotalVulnerabilities]}
Total Open/Not Fixed Vulnerabilities which are Not Informational:
{$value[TotalNotFixedVulnsExInfo]}
Total Vulnerabilities for All Affected Assets:
{$value[TotalRetestVulnsExInfo]}
Total Vulnerabilities for All Affected Assets:
{$value[TotalFixedVulnsExInfo]}
The logic above works as follows:
- Declare dynamic variables that we will use as counters e.g. {$declare..}
- Loop through every vulnerability
- Loop through every instance (affected asset) for every vulnerability
- Increment the counter for total vulnerabilities by 1
- Check if remediation status for the affected asset includes 'Open' and check if the priority is not "Info" - if condition is met, increment the counter for total Open/Not Fixed Not-Info vulnerabilities by 1
- Check if remediation status for the affected asset includes 'Ready for Retest' and check if the priority is not "Info" - if condition is met, increment the counter for total Ready for Retest Not-Info vulnerabilities by 1
- Check if remediation status for the affected asset includes 'Closed' and check if the priority is not "Info" - if condition is met, increment the counter for total Closed/Fixed Not-Info vulnerabilities by 1
- Print the values of the counters
You can add conditional logic to your template in order to change the default icons/images that are used for attack chains.
For example, if you wish to change the "External Attacker" Icon - you can add the following logic to your template:
{#type==”External Attacker”}<INSERT YOUR IMAGE HERE>{/}

Replacing the following attack chain types are supported:
{#type==”External Attacker”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Internal Attacker”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Defender”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Victim”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Action”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Exploit Critical Vulnerability”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Exploit High Vulnerability”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Exploit Medium Vulnerability”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Exploit Low Vulnerability”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Exploit Info Vulnerability”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Target Device”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Target Server”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Target Database”}<INSERT YOUR IMAGE HERE>{/}
{#type==”Captured Flag”}<INSERT YOUR IMAGE HERE>{/}
You can create logic to test if the affected assets are greater than a defined value, and if so, have separate logic.
For example, we want the report to print up to five (5) affected assets - and if there are more than 5, to instead inform the user to check the appendix.
For example:
{#vulnerabilities}
{#affected_assets[5]}
Too many affected assets… see appendix
{/}
{^affected_assets[5]}
{#affected_assets}
{asset}
{/}{/}{/}
{#affectedassets[5]} checks to see if there is a sixth item in the affected assets array/list, and if so, to print 'Too many affected assets… see appendix'. Remember, arrays/list start at 0 hence the sixth value is [5].
{^affectedassets[5]} has the opposite affect of above. It will print the affected asset name for the first five affected assets. It will do this because there is not a sixth item in the array/list - therefore knowing that the affected assets are five or less.
When creating your template, it is important to pay attention to where you are inserting your closing tags {/}.
For example:
{#vulnerabilities}{title}{/}
Will print in the report:
titletitletitletitle
If we want a comma and whitespace between each title:
{#vulnerabilities}{title}, {/}
It will print in the report:
title, title, title, title
However if we adjust the titles to be on different lines:
{#vulnerabilities}
{title}{/}
It will print in the report:
title
title
title
title
Now if we wanted to include a line break between each title:
{#vulnerabilities}
{title}
{/}
It will print in the report:
title
title
title
title
You can also add a new page using the tag {@pageBreak}.
An object is a standalone property, with its own sets of key/value pairs. This term should be familiar to anybody who has worked with Javascript or JSON.
In ReportGen, the vast majority of tags you can access are presented as objects. This means you can access their properties (keys/values) like so:
{#vulnerabilities}
{title}
{/}
The example above will start by looping through each vulnerability object inside the vulnerabilities array/list, then print the title.
The example below will loop through each vulnerability object inside the vulnerabilities array/list, then print the title, then it will loop through each of the affected asset objects, and print the asset name.
{#vulnerabilities}
{title}
{#affected_assets}
{asset}
{/}{/}
You can determine if the tag is a property on an object as it will be represented as key enclosed in two single curly braces i.e. {key}
There are two (2) different types of arrays/lists used in ReportGen:
- Array of Objects
- Array of Strings
An array of objects will appear as follows in ReportGen JSON files and in the browser debugging:
"vulnerabilities:":
[
{
"title": "...",
"priority": "...",
...
},
...
]
Therefore if we wanted to print the title for each vulnerability, we could use the following:
{#vulnerabilities}
{title}
{/}
The example above states:
- FOR EVERY VULNERABILITY
- PRINT TITLE
An array of strings will appear as follows in ReportGen JSON files and in the browser debugging:
"tags:":
[
"...",
"...",
"...",
...
]
You can see the array of strings doesn't have any objects {..} therefore there are no keys we can access. So how do we then print the values in the report? You can do it as follows:
{#tags}
{.}
{/}
Now if you wanted to add an IF condition to an array of objects:
{#vulnerabilities}
{#title == "SQL Injection"}
{title}
{/}{/}
The IF condition is executed on the title key/property of the vulnerability object.
However applying similar condition on array of strings can be achieved as follows:
{#tags}
{#this == "OWASP TOP 10"}
{.}
{/}{/}
Notice that they key/property is this which is a JavaScript notion which means it refers to itself, in this case the value of the tag.
You can extend this to use a filter, for example to only display a tag if it contains a CVE:
{#tags}
{#this | includes:['CVE','cve']}
{.}
{/}{/}
The template above will loop through each tag checking if the tag contains 'CVE' or 'cve' anywhere within the tag, and if so, it will print it.
To insert an image, you must include % symbol at the beginning of the tag, for example {%...}.
An example to automatically insert inline screenshots into the report for Steps to Reproduce / Proof of Concept:
{#vulnerabilities}
{#affected_assets}
{#proof_of_concept}
{text}
{%inlineScreenshot}
{/}{/}{/}
Note: images will be automatically resized to fit within the report. If a caption exists for the image, it will be displayed directly beneath the image.
For details on working with custom tags and custom fields, please see Creating Custom Tags within Individual Reports
ReportGen is built with debugging enabled in the browser console. This can help you to better understand the tags and data structures which represent the tags.
To access debugging information, open you browser console and try to run the report:

If your template is not passing the validation check, you will see the error in the browser console:

Last modified 1yr ago