This page contains:
As of v4.9 of Dradis, you can now use Liquid to refer to content across sections. For example, maybe you want to use document properties inside Content Blocks, so you can refer to the dradis.client inside the Executive Summary Content Block, or perhaps you want to refer to the Node label inside a piece of evidence? Now you can! You can even use conditionals - for example, perhaps you want to be able to have a single Issue able to export to both an English and a Spanish template, without having duplicate fields. Conditional Liquid syntax makes that possible!
A list of the Liquid Drops available is below, but here is an example. If you put this content into an Issue:
#[Description]#
Tag Name:
{% for tag in issue.tags %} {{ tag.name}} {%endfor%}
CVSSv3 score:
{{ issue.fields['CVSSv3.BaseScore'] }}
The {{ issue.title }} issue has {{ issue.evidence.size }} instances of Evidence
With Liquid Dynamic Content, the output in your UI should look something like this:
If you put this into a piece of Evidence:
#[Location]#
tcp/80
#[Output]#
Evidence location:
{{ evidence.fields["Location"] }}
Evidence issue title:
{{ evidence.issue.title }}
Node:
{{node.label}}
The output in your UI should look something like this:
If you put this into a Note:
#[Title]#
Details
#[Project]#
This project is called: {{project.name}}
The output should look something like this:
If you put this content into a Content Block:
#[Description]#
Author email: {{ content_block.author.email }}
Author name: {{ content_block.author.name }}
The output in your UI should look something like this:
Liquid Drops are the way that you can insert dynamic content into projects. Drops use the {{ }} syntax.
We have drops available for most content types inside of your Dradis project:
You can use Liquid to create if statements in projects. For example, if you use multiple templates and your project content has to suit several of them at once, for example for multiple languages, then you can use a conditional like this:
#[Title]#
{% if document_properties.dradis.lang == 'en' %}
Testing
{% elsif document_properties.dradis.lang == 'fr' %}
Essai
{% endif %}
#[Description]#
{% if document_properties.dradis.lang == 'en' %}
This is a test
{% elsif document_properties.dradis.lang == 'fr' %}
C'est un test
{% endif %}
In the example above, if the dradis.lang document property is set to en then the project will export in English; if it is set to fr it will export in French.
One note: for code block styling within conditionals, you would need to add {%raw%}{%endraw%} tags as well to avoid errors. Here's a sample of what that would look like:
{% if evidence.fields['Request'] != "n/a" %}
{%raw%}bc.. {{ evidence.fields['Request'] }}{%endraw%}
{% endif %}
Content Blocks are found on the Report Content page of your project.
The following drops are available:
{{ content_block.author }}
{{ content_block.block_group }}
{{ content_block.content }}
{{ content_block.fields['Field Name'] }}
Document Properties are found on the Report Content page of your project.
The following drops are available:
{{ document_properties.dradis.example }}
For example, if you have a Document Property called dradis.client, you can refer to it as {{ document_properties.dradis.client }}.
The following drops are available:
{{ evidence.content }}
{{ evidence.fields['Field Name'] }}
{{ evidence.id }}
{{ evidence.issue }}
{{ evidence.title }}
Evidence cannot be accessed on their own, but must be within issues or nodes.
However, that means you can also refer directly to drops from issues or nodes where the evidence is found. For example, you can use evidence.node.properties['hostname'] to get the value of the hostname property for the node where a piece of evidence is located. Similarly, you could use evidence.issue.fields['CVSSv3.Vector'] to get the value of the CVSSv3.Vector field for the issue that the evidence is associated with.
To show a count of Evidence for a specific Issue you can use something like issue.evidence.size.
The following drops are available:
{{ issue.affected }}
{{ issue.author }}
{{ issue.evidence }}
{{ issue.fields['Field Name'] }}
{{ issue.id }}
{{ issue.tags }}
{{ issue.text }}
{{ issue.title }}
The following drops are available:
{{ node.properties["property name"] }}
{{ node.evidence }}
{{ node.id }}
{{ node.label }}
{{ node.notes }}
The following drops are available:
{{ note.fields['Field Name'] }}
{{ note.id }}
{{ note.text }}
{{ note.title }}
{{ note.updated_at }}
The following drops are available:
{{ project.authors }}
{{ project.id }}
{{ project.name }}
{{ project.updated_at }}
Tags are used to categorize Issues. The default tags are Critical, High, Medium, Low, and Info.
The following drops are available:
{{ tag.color }}
{{ tag.display_name }}
{{ tag.id }}
{{ tag.name }}
{{ tag.tag_issues }}
Each project can be associated with a Team.
The following drops are available:
{{ team.name }}
The Liquid drops mentioned above are available anywhere in your Dradis project. They will also export to Word, Gateway, and HTML (not Excel!) as expected.
For example, this pasted inside an Issue will export to Word or HTML:
#[Description]#
{{ project.name }} for {{ team.name }} team
{{document_properties.available_properties}}
Tag Name:
{% for tag in issue.tags %} {{ tag.name}} {%endfor%}
CVSSv3 score:
{{ issue.fields['CVSSv3.BaseScore'] }}
Evidence:
{% for evidence in issue.evidence %} {{ evidence.fields["Label"] }} {%endfor%}
The {{ issue.title }} issue has {{ issue.evidence.size }} instances of Evidence
Evidence count per node:
{% for node in issue.affected %}
{{ node.properties["hostname"] }} has {{node.evidence.size}} instances of evidence
{% endfor %}
Use this code at the Issue level to build a table with a new row for each instance of Evidence:
table(Style2).
|_. Host |_. Port |
{% for evidence in issue.evidence %}| {{ evidence.fields["Label"] }} | {{ evidence.fields["Location"] }}|
{%endfor%}
Burp HTML reports give their Request/Response data in up to 4 fields:
We've seen cases where only _3 is populated, not the other 3 tags. This can lead to a string of 3 n/a values before the data you care about.
Instead, we can use Liquid and the Mappings Manager to ignore the n//a values:
*Request*
{% if evidence.fields['Request'] != 'n/a' %}bc.. {{ evidence.fields['Request'] }}{% endif %}
{% if evidence.fields['Request1'] != 'n/a' %}bc.. {{ evidence.fields['Request1'] }}{% endif %}
{% if evidence.fields['Request2'] != 'n/a' %}bc.. {{ evidence.fields['Request2'] }}{% endif %}
{% if evidence.fields['Request3'] != 'n/a' %}bc.. {{ evidence.fields['Request3'] }}{% endif %}
The example here focuses on Request, but the same logic can be used for Response.
This Liquid snippet designed to be put into an Evidence field to pull in the corresponding Node property. If there is a hostname, that is pulled in. If not, the FQDN name is pulled in.
{% capture hostname %}{{ evidence.node.properties['hostname'] | default: '' }}{% endcapture %}
{% capture fqdn %}{{ evidence.node.properties['fqdn'] | default: '' }}{% endcapture %}
{{ hostname != '' | default: fqdn != '' | default: 'n/a' }}
The min_rows_for_table variable controls the minimum threshold of affected Nodes required to start splitting them into columns.
The desired_columns variable controls how many table columns will be generated.
{% assign desired_columns = 3 %}{% assign min_rows_for_table = 12 %}{% assign uniq = "" %}{% assign buffer = "" %}{% for a in issue.affected %}{% assign label = a.label | strip %}{% unless uniq contains label %}{% assign uniq = uniq | append: label | append: "||" %}{% if buffer == "" %}{% assign buffer = label %}{% else %}{% assign buffer = buffer | append: "
" | append: label %}{% endif %}{% endunless %}{% endfor %}{% assign rows = buffer | split: "
" %}{% assign count = rows | size %}{% if count > min_rows_for_table %}{% assign table = "" %}{% assign col = 0 %}{% for r in rows %}{% if r != "" %}{% if col == 0 %}{% assign table = table | append: "|" %}{% endif %}{% assign table = table | append: r | append: "|" %}{% assign col = col | plus: 1 %}{% if col == desired_columns or forloop.last %}{% if col < desired_columns %}{% assign remaining = desired_columns | minus: col %}{% for i in (1..remaining) %}{% assign table = table | append: "|" %}{% endfor %}{% endif %}{% assign table = table | append: "
" %}{% assign col = 0 %}{% endif %}{% endif %}{% endfor %}{{ table }}{% else %}{% for r in rows %}{{ r }}{% endfor %}{% endif %}
Next help article: Combine multiple Issues →
Your email is kept private. We don't do the spam thing.