Back to home

DocsReport templates

Turn one Word file into a finished pentest report.

Design your report once, mark where the data goes, and PentOne fills it in from your project - findings, tables, colors, and all.

01

Getting started

What a template is, and how to build your first one in five minutes.

What is a template?

What templates are, why they exist, and when to use one.

A template is a fill-in-the-blank version of your report. You design the layout once headings, tables, branding, wording and mark the spots where real data should go. When you generate a report, PentOne swaps every mark for real data from your project.

Template
Client: {{project.client-name.TXT}}
Report output
Client: Acme Corporation

Why it exists: penetration-test reports share 90% of their structure every time. Templates standardize that structure once, then produce a polished report for any project in seconds consistent branding, zero manual formatting.

Use a template when
You write more than one report a month, need a consistent house style, or want findings, counts, and tables filled in automatically.
You may skip it when
You're producing a one-off, free-form document with no repeating findings. Even then, a template rarely hurts.

How generation works

The 11-step pipeline PentOne runs every time you generate a report.

Understanding the pipeline makes every feature obvious. When you generate, PentOne runs these steps in order:

1
Read
Open your template (DOCX).
2
Parse
Find every {{placeholder}}, every /// marker, and every scoring type code.
3
Fetch
Pull your project data and all findings.
4
Score
Run each finding through its scoring frameworks (CVSS, CWE, OWASP RR…). A score is never invented - only computed from what you supplied.
5
Rank
Order findings by combined risk, highest first - correctly, even when findings use different scoring frameworks.
6
Replace
Swap simple placeholders for real values.
7
Expand
Duplicate each /// section once per finding.
8
Fill rows
Add one MLTIRW table row per finding.
9
Style
Apply severity colors, embed images, format rich text & code.
10
Build TOC
Generate the table of contents.
11
Clean
Remove any leftover {{...}} that had no data.
12
Export
Save as DOCX (and PDF on request).
Two things to remember
Findings are ranked automatically by risk, highest first - you can't hand-order them. The ranking fuses whatever scoring frameworks each finding carries, so it works even when different findings use different frameworks (see Severity ordering). And leftover placeholders are deleted, not printed - a blank result means missing data, an unscored framework, or a name mismatch.

Quickstart (5 min)

Build your first working template in five minutes.

Copy this into a blank Word document and you'll have a working report in five minutes.

1

Paste this into Microsoft Word

my-first-template.docx
SECURITY ASSESSMENT REPORT

Date:    {{report.export-date.DATE.AUTO}}
Client:  {{project.client-name.TXT}}
Website: {{project.target-url.URL}}

Summary of findings:
- Critical: {{critical.sum}}
- High:     {{high.sum}}
- Medium:   {{medium.sum}}
- Low:      {{low.sum}}
- Info:     {{info.sum}}

DETAILED FINDINGS

///
{{vulnerability.title.BOLD.TXT}}

Severity: {{vulnerability.severity.ADCLR}}
CVSS:     {{vulnerability.cvss-score.ADCVSSS}}

What we found:
{{vulnerability.description.ADBLTN}}

How to fix it:
{{vulnerability.remediation.ADBLTN}}
///
2

Save as a .docx file

Use .docx, not .doc.
3

Upload it

In your workspace, go to Templates → Upload. DOCX files are accepted, up to 10 MB.
4

Generate

Open the Report page and generate. PentOne fills the date and client details, counts findings, creates one detailed block per finding, colors each severity, and gives you a document to download as DOCX or PDF.
Tip
That's a complete report. Everything below explains each piece and how to go further. You can also download a ready-made example template.
02

Placeholders

The syntax every placeholder in a template is built from.

Placeholder anatomy

The three-part syntax behind every placeholder.

A placeholder is a code that means “put the real value here.” It always has three parts:

{{scope.field-name.TYPE}}
scope
WHERE the data comes from
project · vulnerability · report
field-name
WHICH piece of data
client-name · CLIENT-NAME · client_name
TYPE
HOW it looks / behaves
TXT · ADBLTN · ADBLOCK · ADCLR
You wantPlaceholderOutput
Client name{{project.client-name.TXT}}Acme Corporation
Report date (auto){{report.export-date.DATE.AUTO}}2026-07-06
Finding title, bold{{vulnerability.title.BOLD.TXT}}SQL Injection
Severity with color{{vulnerability.severity.ADCLR}}Critical (red cell)
The golden rules
  • Field names are fully dynamic use whatever you named the field (client-name, CLIENT-NAME, client_name are all valid if that is the name you defined).
  • No spaces, ever. {{project.Client Name.TXT}} will not work use hyphens or underscores.
  • The scope word is case-insensitive; the field name must match your definition exactly.
  • Type the whole placeholder in one go see the #1 problem for why this matters in Word.
A grammar, not a fixed field list
PentOne placeholders work like a small language for Word. The engine parses syntax scope, field name, type codes, table coordinates (TBL/CLM), repeat tags (MLTIRW), and modifiers (.AUTO). Examples like client-name, serial-no, or proof-of-concept in this guide are demos you define your own field names. A few system patterns (critical.sum, toc.*.AUTO, number.*.MLTIRW.AUTO) are engine-calculated; everything else is yours.

Scopes

Where placeholder data comes from - project, vulnerability, report, and system scopes.

The first word the scope tells the engine what kind of data feeds the placeholder. Scopes fall into two groups:

Data scopes you (or your findings) provide the values

ScopeWhat it representsRepeats?Typical use
projectEngagement metadata and project-level listsNo / list fieldsCover page, executive summary, scope tables
vulnerabilityOne findingYes per findingDetail sections, findings tables
reportDocument metadataNoExport date (with .AUTO)

System scopes PentOne calculates the values

These are not like project or vulnerability. They are reserved pseudo-scopes the engine recognizes by syntax. You don't create fields for them in project settings they work because of the pattern, not because you named a field.

ScopeWhat PentOne fillsReserved patternTypical use
critical…infoSeverity counts{{critical.sum}}Executive summary counts
numberRow numbers 1, 2, 3…number.*# column in MLTIRW tables any field name you choose
tocTable of contentstoc.*.AUTOTOC page
How to build scope / target tables
  • For a repeating target list (many rows), use project.* with .MLTIRW e.g. {{project.target-name.TXT.TBL2.CLM2.MLTIRW}}.
  • For a single-value table (one row, one value per cell), use the simple form e.g. {{project.target-name.TXT}}. No TBL, CLM, or MLTIRW needed.
  • Fill project fields on the Report page's project-scope form.

project one value per report

Facts about the engagement, the same everywhere in the document.

{{project.client-name.TXT}}      Client company name
{{project.target-url.URL}}       Main website / scope URL
{{project.contact-name.TXT}}     Client contact person
{{project.contact-email.EMAIL}}  Contact email
{{project.lead-assessor.TXT}}    Who performed the test
{{project.reviewer-name.TXT}}    Who reviewed the report
{{project.start-date.DATE}}      Engagement start
{{project.end-date.DATE}}        Engagement end
Note
These field names are examples. The real names are whatever you defined in your project settings.

vulnerability one value per finding

Only meaningful inside a repeating section (///…///) or a repeating table row (.MLTIRW), because there are many findings.

{{vulnerability.title.TXT}}                 Finding title
{{vulnerability.severity.ADC}}              Severity label
{{vulnerability.severity.ADCLR}}            Severity + colored cell
{{vulnerability.description.ADBLTN}}         Full description (rich text)
{{vulnerability.impact.ADBLTN}}             Business impact
{{vulnerability.remediation.ADBLTN}}        How to fix
{{vulnerability.proof-of-concept.ADBLOCK}}  Evidence / steps (code block)
{{vulnerability.cvss-score.ADCVSSS}}        CVSS score (0-10)
{{vulnerability.cvss-vector.ADCVSSV}}       CVSS vector string
{{vulnerability.affected-url.URL}}          Where the issue lives
Note
Field names like title, description, proof-of-concept are examples name them whatever fits your template. The engine matches syntax and type codes, not a fixed vocabulary.

project multi-row fields repeating scope / target tables

Only when the table should grow to many rows one row per target in your project-scope list. Use .MLTIRW on that single template data row:

{{project.target-name.TXT.TBL2.CLM2.MLTIRW}}   Target name (repeats)
{{project.target-url.URL.TBL2.CLM3.MLTIRW}}     Target URL (repeats)
{{project.target-type.TXT.TBL2.CLM4.MLTIRW}}    Target type (repeats)
Single-row table? Keep it simple
If the table has only one data row and each cell holds a single project value, skip TBL/CLM/MLTIRW entirely:
{{project.target-name.TXT}}
Same rule applies anywhere cover page, summary table, or a one-line scope cell.

report & system helpers

{{report.export-date.DATE.AUTO}}   Today's date (system-calculated)

{{critical.sum}}  {{high.sum}}  {{medium.sum}}  {{low.sum}}  {{info.sum}}

{{number.serial-no.TBL1.CLM1.MLTIRW.AUTO}}   # column row 1, 2, 3…
{{toc.table-of-contents.AUTO}}               Table of contents
The number scope auto row indices
  • number is a system pseudo-scope not for project or vulnerability data. Use it only in the # column of MLTIRW tables.
  • The field name is yours serial-no, row-index, idx, or anything else. Same grammar as project.client-name; nothing is hard-reserved about the name.
  • Add .AUTO so PentOne fills 1, 2, 3… at generation e.g. {{number.serial-no.TBL1.CLM1.MLTIRW.AUTO}} or {{number.row-index.TXT.TBL1.CLM1.MLTIRW.AUTO}}.
Watch out
Don't put vulnerability.* placeholders outside a /// section or MLTIRW row PentOne won't know which finding you mean, and it'll come out blank.

Type codes

How each type code renders text, rich content, colors, and scores.

The last part of a placeholder is the type code. It tells PentOne how to render the value. Most types just print text; a few are “smart” and do real formatting.

Smart types (they do something)

CodeWhat it doesUse it forExample
BOLDBold text (combine with TXT)Finding titles, section labels{{vulnerability.title.BOLD.TXT}}
ADCLRFills the table cell with a severity colorSeverity column in summary tables{{vulnerability.severity.ADCLR}}
ADBLTNRich text paragraphs, bullet & numbered listsDescription, impact, remediation (text & lists only){{vulnerability.description.ADBLTN}}
ADBLOCKBlock editor images, tables, code blocks, mixed evidencePoC, evidence, screenshots, commands, reproduction steps{{vulnerability.proof-of-concept.ADBLOCK}}
SIGRenders a signature (image or text)Sign-off / approval blocks{{project.reviewer-signature.SIG}}
DATE.AUTOToday's date, ISO formatReport date{{report.export-date.DATE.AUTO}}

Choosing the right smart type

Area in your templateUse thisWhy
Finding titleBOLD.TXTShort bold label
Severity in a table cellADCLRAuto-colored background
Description, impact, remediation (paragraphs + bullets only)ADBLTNRich text lists no images or code blocks
Proof of Concept, evidence, screenshots, commandsADBLOCKFull block editor images, code, and text together
Reviewer sign-offSIGSignature image or text
Rule of thumb
If a section might contain screenshots, code, or mixed evidence, use ADBLOCK not ADBLTN. ADBLTN is enough when you only need paragraphs and lists.

Plain types (they print the value as text)

CodeMeaning
TXTPlain text (the default)
URLA web address
EMAILAn email address
NUMA number
DATEA date you entered
TIMEA time
PERCA percentage value (0-100)
ADCA category label (e.g. severity, no color)
ADCVSSSA CVSS score
ADCVSSVA CVSS vector string
ALLThe full raw content of a field
Note
Dates always print as YYYY-MM-DD (e.g. 2026-07-06). That format is fixed restyle in Word after generating if you need a different look.
Scores, vectors & severity are their own world
ADCVSSS, ADCVSSV, ADCLR and ADC above are only the tip of it. Severity, scores, vectors, CWE, EPSS, SSVC, DREAD and a dozen other frameworks are produced by PentOne's scoring engine, which has its own family of type codes. If your report shows any risk rating, read How scoring works next it is the other half of the language.
What about .AUTO?
.AUTO is not a type code it marks system-managed placeholders PentOne fills at generation. See The .AUTO modifier.

The .AUTO modifier

System-managed placeholders PentOne calculates at generation.

.AUTO is not a type code like TXT or ADCLR. It is a suffix on specific placeholders that tells PentOne: calculate this at report generation the user never types a value.

Backend behavior
On the backend, any placeholder containing .AUTO is marked system-managed. It is excluded from project and vulnerability forms testers do not fill it in. PentOne computes the value when you click Generate.

The three places .AUTO is used

PlaceholderWhat PentOne fills inWhen you need it
{{report.export-date.DATE.AUTO}}Today's date (YYYY-MM-DD)Cover page, header always generation day
{{number.serial-no.TBL1.CLM1.MLTIRW.AUTO}}Row numbers 1, 2, 3…The # column in any MLTIRW table
{{toc.table-of-contents.AUTO}}Clickable table of contentsTOC page built from document headings

Examples

Cover page date (always today):
{{report.export-date.DATE.AUTO}}

Findings table # column (TBL1):
| {{number.serial-no.TBL1.CLM1.MLTIRW.AUTO}} | {{vulnerability.title.TXT.TBL1.CLM2.MLTIRW}} | ...

Scope table # column (TBL2):
| {{number.serial-no.TBL2.CLM1.MLTIRW.AUTO}} | {{project.target-name.TXT.TBL2.CLM2.MLTIRW}} | ...

Table of contents (place exactly where TOC should appear):
{{toc.table-of-contents.AUTO}}

How important is it?

Without .AUTOWith .AUTO
Manually enter report date on every projectDate fills itself every generation
Number table rows by hand or leave # blankRows auto-number 1, 2, 3…
TOC missing or in wrong placeTOC generated exactly at the placeholder
Why .AUTO only on the # column not on every MLTIRW cell
In a multi-row table, only engine-calculated columns need .AUTO. The row-number column uses number.*…MLTIRW.AUTO (any field name you pick) because PentOne generates 1, 2, 3… itself. Data columns like {{vulnerability.title.TXT.TBL1.CLM2.MLTIRW}} have no .AUTO testers fill those via findings. Putting .AUTO on a data column would mark it system-managed and exclude it from forms without filling it.

number scope auto row numbering

number is not a scope for project or vulnerability data. It is a system pseudo-scope for the # column in MLTIRW tables. The field-name slot works like everywhere else pick any name (serial-no, row-index, idx). What makes it auto-fill is number scope + .MLTIRW + .AUTO, not a magic reserved word.

PartRole
numberSystem scope calculated row index, not user data
your field nameFree choice e.g. serial-no, row-index (demo names only)
TBL1 / CLM1Which table and column this # cell belongs to
MLTIRWThis row repeats number increments per row
.AUTOSystem-managed excluded from forms; PentOne writes 1, 2, 3…

What .AUTO is NOT

  • Do not add .AUTO to regular fields like {{project.client-name.TXT.AUTO}} it will not auto-fill client names.
  • DATE alone is a date you enter ({{project.start-date.DATE}}). DATE.AUTO is a date PentOne sets ({{report.export-date.DATE.AUTO}}).
  • Severity counts ({{critical.sum}}) are system-managed too, but use .sum, not .AUTO.

Custom fields & naming

Define your own fields and name them safely.

PentOne's field system is fully dynamic. You're not limited to the fields in this guide define your own custom fields on a project and reference them by name.

Template
Custom field "engagement-code"
Report output
{{project.engagement-code.TXT}}

The naming rules (these matter)

RuleStatusExample
No spaces✗ Not allowed{{project.Client Name.TXT}}
Hyphens✓ Works{{project.client-name.TXT}}
Underscores✓ Works{{project.client_name.TXT}}
Mixed case✓ WorksCLIENT-NAME · client_Name
Must match definitionRequiredField name in placeholder = field name in project settings
Watch out
The engine cannot read a placeholder that contains a space it will be left blank. Letters, numbers, hyphens, and underscores are all fine; case must match your field definition. If a placeholder comes out empty, check the exact field name (including case) and try hyphen vs underscore.
03

Repeating content

Turning one section or one table row into many - once per finding.

Repeat a section per finding

Repeat a block once per finding with /// markers.

This is the feature that turns a template into a real report. Wrap a block in /// markers and PentOne repeats it once for every finding.

template
///
{{vulnerability.title.BOLD.TXT}}
Severity: {{vulnerability.severity.ADCLR}}
Description: {{vulnerability.description.ADBLTN}}
///
Both markers are exactly three slashes
The first /// (on its own line) is the start; the second /// is the end. Not two slashes, not four.

If your project has 3 findings, PentOne produces 3 copies of everything between the markers each with that finding's data, ranked by risk (highest first):

output
SQL Injection
Severity: Critical        (red)
Description: The login form...

Cross-Site Scripting
Severity: High            (orange-red)
Description: A reflected XSS...

Missing Security Headers
Severity: Low             (green)
Description: HSTS is not set...
✓ Do
Put each /// on its own line. Keep every vulnerability.* placeholder between the markers.
✗ Don't
Don't put text on a /// line. Don't nest loops. Don't put project info inside unless you want it repeated on every finding.

Repeat table rows (MLTIRW)

Grow tables one row per finding with MLTIRW.

MLTIRW means multi-row PentOne duplicates one template data row into many rows at generation time. Use it only when a table should repeat (findings list, multi-target scope list, etc.).

When you do NOT need MLTIRW
  • A table with one data row and one value per cell does not repeat use the simple placeholder.
  • Repeating: {{project.target-name.TXT.TBL2.CLM2.MLTIRW}} many targets, many rows.
  • Single value: {{project.target-name.TXT}} one target, one cell. No TBL, CLM, or MLTIRW.
  • Same logic for project.*, and for any non-repeating table cell in the document.
The core idea
  • Template: 1 header row + 1 data row with MLTIRW placeholders.
  • Generated report: 1 header row + N data rows (one per finding or project list item).
  • Never add blank rows for future findings PentOne clones the single data row for you.

Anatomy

placeholder breakdown
{{ vulnerability . title . TXT . TBL1 . CLM2 . MLTIRW }}
   scope         field   type  table#  col#   repeat tag
1

Build a normal table in Word

Header row + exactly one data row.
2

Put MLTIRW placeholders in that single data row

Every placeholder in the same table shares the same TBL number; CLM matches column order.

Example A Findings table (TBL1, vulnerability scope)

one data row
| # | Finding | Severity | CVSS |
|---|---------|----------|------|
| {{number.serial-no.TBL1.CLM1.MLTIRW.AUTO}} | {{vulnerability.title.TXT.TBL1.CLM2.MLTIRW}} | {{vulnerability.severity.ADCLR.TBL1.CLM3.MLTIRW}} | {{vulnerability.cvss-score.ADCVSSS.TBL1.CLM4.MLTIRW}} |

Example B Scope / target table (TBL2, project scope)

second table in same report
| # | Target | URL | Type |
|---|--------|-----|------|
| {{number.serial-no.TBL2.CLM1.MLTIRW.AUTO}} | {{project.target-name.TXT.TBL2.CLM2.MLTIRW}} | {{project.target-url.URL.TBL2.CLM3.MLTIRW}} | {{project.target-type.TXT.TBL2.CLM4.MLTIRW}} |

Example C Multiple repeating tables in one report

TableTBL #ScopeRepeats per
Findings overviewTBL1vulnerabilityfinding
Scoped targetsTBL2projectproject list item
Custom checklistTBL3projectlist item
three tables, three TBL numbers
FINDINGS (TBL1)
| {{number.serial-no.TBL1.CLM1.MLTIRW.AUTO}} | {{vulnerability.title.TXT.TBL1.CLM2.MLTIRW}} | ...

SCOPE (TBL2)
| {{number.serial-no.TBL2.CLM1.MLTIRW.AUTO}} | {{project.target-name.TXT.TBL2.CLM2.MLTIRW}} | ...

TEST ACCOUNTS (TBL3)
| {{number.serial-no.TBL3.CLM1.MLTIRW.AUTO}} | {{project.test-account.TXT.TBL3.CLM2.MLTIRW}} | {{project.test-role.TXT.TBL3.CLM3.MLTIRW}} |
PartMeaning
TBL1Table 1 in this document. Use TBL2, TBL3… for each additional repeating table.
CLM1Column 1 (CLM2 = column 2, etc.). Must match left-to-right order.
MLTIRWDuplicate this row for every item in the data set.
.AUTOOnly on # column (number.*) marks engine-calculated values
Which columns get .AUTO?
Only the # column. {{number.serial-no.TBL1.CLM1.MLTIRW.AUTO}} uses .AUTO because row numbers are engine-calculated. Data columns like {{vulnerability.title.TXT.TBL1.CLM2.MLTIRW}} have no .AUTO those values come from findings you enter.
Rules
  • One data row per table no extra blank rows.
  • Same TBL number for every placeholder in the same table.
  • New TBL number for each separate repeating table.
  • number scope + any field name + .AUTO is for the # column only serial-no in examples is just a demo name.
04

Scoring & severity

How severity, scores, and risk ranking work for CVSS and every other framework.

How scoring works

The universal scoring model behind every severity, score, and vector placeholder.

Every severity label, risk score, and vector string in a PentOne report is produced by a scoring framework. A finding is not simply “a Critical” it carries one or more framework assessments, and your template places their outputs. Grasp this one idea and every score placeholder becomes obvious.

One finding, many frameworks

A single finding can be scored by several frameworks at once CVSS for the technical severity, CWE for the weakness class, EPSS for exploitation likelihood, SSVC for the action decision. Each framework filled in on the finding becomes an assessment, and each assessment can render a score, a vector, a severity band, and its own framework-specific parts.

Template
CVSS {{vulnerability.cvss-score.ADCVSSS}} / {{vulnerability.cwe-id.ADCWE}}
Report output
CVSS 9.8 / CWE-89: SQL Injection
You place outputs, not inputs
Testers fill the framework calculators on each finding (the CVSS dropdowns, the DREAD sliders, the CWE picker). Your template only places the outputsthe score, band, vector, or a specific field. If a finding was never scored with a framework, that framework's placeholders render blank (see below).

The four kinds of scoring

Not every framework answers the same kind of question, and that is the key to how they combine. Every framework declares its kind:

KindWhat it doesFrameworksIn the report
OrdinalRanks severity on a scaleCVSS, CWE estimate, OWASP RR, DREAD, legacy, customScore + severity band
CategoricalClassifies never ranksSTRIDE, KEV, CVE, CAPEC, ATT&CK, CWE as a classA label / identifier
ProbabilityLikelihood of exploitationEPSSA percentage
DecisionA prioritisation verdictSSVCAct / Attend / Track* / Track
Note
Why it matters: an ordinal score, a probability, and a decision are not the same unit, so PentOne never averages them together. It fuses ordinal scores, uses probability as a multiplier, and lets a decision set a floor. That is the whole subject of Severity ordering.

Severity bands & their colours

Ordinal frameworks map their score onto a five-step ladder. These are the exact colours PentOne shades report cells with when you use ADCLR (click any swatch to copy its hex):

Some frameworks use bands that fit them SSVC uses Track / Track* / Attend / Act, EPSS uses Very Low through Very High but the colour always comes from the framework that owns the band, so a shaded cell is always honest about which framework produced it.

Two rules that never bend

A score is never invented
If a finding has no CVSS vector, there is no CVSS score. PentOne will not manufacture a number from a severity label. An unscored placeholder renders empty and is cleaned up, never guessed.
Every score carries provenance
Each assessment records where it came from Human, Calculated (e.g. the CWE estimate from NVD data), Imported (a scanner or feed), or AI-suggested so a number in your report can always be defended.

Three ways to choose a framework in a placeholder

Most templates use the dedicated code it is the clearest. But the engine can resolve a framework three ways:

WayExampleWhen to use it
Dedicated code (recommended){{vulnerability.score.ADCVSSS}}The normal case one code per framework output
Field name = framework{{vulnerability.owasp-rr.ADSCORE}}Generic ADSCORE/ADVEC/ADBAND, framework named in the field slot
Framework as a modifier{{vulnerability.risk.ADSCORE.CVSS}}Generic code, framework pinned by a trailing modifier
The generic trio
ADSCORE, ADVEC and ADBAND are framework-neutral score, vector, and band for whichever framework the placeholder resolves to. With no framework named, they fall back to your workspace's primary scoring system. Use them for a report that should follow whatever framework a client has standardised on, without hard-coding CVSS.
✓ Good practice
Use the dedicated code for the framework you mean (ADCVSSS, ADCWE, ADEPSS). Keep every score placeholder inside a /// finding section or a MLTIRW row so it resolves against a specific finding.
✗ Bad practice
Don't expect a severity on a finding nobody scored a blank is the system refusing to invent one. Don't place vulnerability.* score codes outside a finding loop.

CVSS (3.1 / 3.0 / 4.0)

The CVSS placeholders every template already uses - plus every base, temporal, and environmental metric on its own.

CVSS is the default framework and the one every existing template already speaks. Three codes cover almost every report; the rest let you place any single metric on its own line.

The three you already know

CodeRendersUse it for
ADCVSSSThe CVSS base score, e.g. 9.8Score cell in a finding header or summary table
ADCVSSVThe CVSS vector stringA "vector" line under the score
ADCLRThe severity band + shades the cellThe severity column / label
finding header
Severity: {{vulnerability.severity.ADCLR}}
CVSS:     {{vulnerability.cvss-score.ADCVSSS}}
Vector:   {{vulnerability.cvss-vector.ADCVSSV}}
The score comes from the vector never the label
CVSS is computed from the vector string built in the calculator. If a stored score and its vector disagree, the vector wins and the mismatch is flagged. This is deliberate: a severity word can never be reverse-engineered back into eight metrics, so PentOne refuses to.

Versions: 3.1, 3.0 and 4.0

  • CVSS 3.1 is the default. ADCVSSS / ADCVSSV / ADCLR resolve to it unless you say otherwise.
  • CVSS 3.0 shares the same base equations; a 3.0 vector is preserved and scored through the same ADCVSSS / ADCVSSV / ADCLR codes above no separate codes needed.
  • CVSS 4.0 is a genuinely different framework it replaces the single impact triad with Vulnerable-System (VC/VI/VA) and Subsequent-System (SC/SI/SA) metrics, and splits Attack Complexity into AC plus a new Attack Requirements (AT). It has its own dedicated codes, below.
  • {{vulnerability.cvss.ADCVSSREV}} prints the version actually used on a 3.x finding, e.g. “3.1”.
CodeRendersUse it for
ADCVSS40SThe CVSS 4.0 scoreScore cell on a v4.0-scored finding
ADCVSS40VThe CVSS 4.0 vector stringA "vector" line under the score
ADCVSS40CThe severity band (shades the cell)The severity column / label
CVSS 4.0 uses its own codes, not ADCVSSS/ADCVSSV/ADCLR
A finding scored with CVSS 4.0 will not show anything through ADCVSSS / ADCVSSV / ADCLR those always mean CVSS 3.1 (or 3.0). Use ADCVSS40S / ADCVSS40V / ADCVSS40C for a v4.0 finding, or the framework-neutral ADSCORE / ADVEC / ADBAND pinned with a CVSS40 modifier (see How scoring works) if your template needs to handle either version in the same cell.

Base, temporal & environmental scores

A report may want to show more than one number side by side:

CodeRenders
ADCVSSBASEBase score only ignores temporal / environmental
ADCVSSTEMPTemporal score (base × exploit maturity × remediation × confidence)
ADCVSSENVSEnvironmental score, re-evaluated against this deployment's requirements

Every metric on its own line

When a finding table needs “Attack Vector: Network” as a row rather than buried in the vector string, each metric has its own code. All render the human-readable label, not the bare letter. Most reports only need ADCVSSS, ADCVSSV and ADCLR reach for these only when a template genuinely lists metrics individually.

Every scoring framework

CWE, OWASP RR, DREAD, EPSS, SSVC, STRIDE, KEV, CVE, CAPEC, ATT&CK, the legacy ladder, and custom frameworks - with their placeholders and calculators.

Beyond CVSS, PentOne ships a full catalog of scoring and classification frameworks. Each one filled in on a finding gains a set of placeholders automatically. Here is every framework, what it answers, and the codes it gives you.

How to read this page
Each framework lists its kind (Ordinal ranks, Categorical classifies, Probability is a likelihood, Decision is a verdict - see How scoring works for the full model), the placeholders it produces, and when to reach for it.
For every code on this page, the field-name segment is just a label it is not read
In {{vulnerability.cwe-id.ADCWE}}, the middle segment cwe-id is not looked up at all it is purely a label for your own readability in the template. {{vulnerability.cwe-id.ADCWE}} and {{vulnerability.literally-anything.ADCWE}} render the exact same value. This is because a finding has at most one assessment per framework CVSS, CWE, DREAD and so on don't repeat within a single finding, so there is nothing for a field name to disambiguate. The type code alone determines what renders. Name it whatever reads clearly in your template (dread, dread-score, my-dread-rating all work identically) renaming it will never change, scope, or duplicate what shows up. This rule applies to every dedicated code on this page (ADCWE*, ADEPSS*, ADDREAD*, ADSSVC*, ADOWASP*, ADCVE*, ADKEV*, ADCAPEC*, ADATTACK*, ADSTRIDE*). It does not apply to the generic ADSCORE/ADVEC/ADBAND codes on the How scoring works page, where the field name (or a modifier) is exactly how you pick the framework.
The mistake that trips up almost everyone: submit flat fields, not one combined field
A framework with more than one input DREAD, SSVC, OWASP Risk Rating, EPSS must have each factor filled in as its own separate field, matching that framework's exact factor names below. Get this wrong (e.g. one field named dread holding all five ratings together) and every placeholder for that framework renders blank the score was never computed because the individual factors were never found as their own fields. A framework with only oneinput (CVE, CAPEC, ATT&CK, STRIDE, KEV) doesn't have this problem there is only one field to fill in.
FrameworkFill in exactly these fields
DREADdamage, reproducibility, exploitability, affected_users, discoverability
SSVCexploitation, automatable, technical_impact, mission
OWASP Risk Ratingskill_level, motive, opportunity, size, ease_of_discovery, ease_of_exploit, awareness, intrusion_detection, loss_of_confidentiality, loss_of_integrity, loss_of_availability, loss_of_accountability, financial_damage, reputation_damage, non_compliance, privacy_violation
EPSSprobability, percentile, cve, date

CWE - Common Weakness Enumeration

Ordinal / Categorical   CWE names the class of weakness (CWE-79 Cross-site Scripting, CWE-89 SQL Injection). It is a taxonomy but PentOne can also give it a defensible severity by re-scoring every NVD CVE mapped to that CWE against your environment (MITRE's “ec3” estimate), and it reports the sample size so you can judge it. With no NVD data it stays a pure classification and no score is invented.

CodeRenders
ADCWEPrimary CWE id. Add .ALL for every id, .TXT or .LABEL for the full label
ADCWELCWE id + name, e.g. CWE-79: Cross-site Scripting
ADCWESEstimated environmental score (mean CVSS across mapped CVEs)
ADCWECSeverity band of that estimate (shades the cell)
ADCWEVThe environmental vector behind the estimate
ADCWENThe evidence: CVE sample size, range and σ

MITRE catalog fields render honestly-empty until the CWE catalog feed is imported, then fill with no template change: ADCWECAT · ADCWEABS · ADCWEDESC · ADCWEEXT · ADCWEPLAT · ADCWEMOI · ADCWECONS · ADCWEDET · ADCWEMIT · ADCWEREL · ADCWECAPEC.

Tip
Use ADCWE in a finding's classification row. Reach for ADCWES / ADCWEC only when a finding is classified but you want a severity estimate and show ADCWEN next to it so the number carries its error bar.

OWASP Risk Rating

Ordinal   Likelihood (eight factors) × Impact (technical or business), each bucketed Low/Medium/High and combined through OWASP's published severity matrix. Ideal when a client expects the OWASP methodology rather than CVSS.

CodeRenders
ADOWASPThe final risk band (Note / Low / Medium / High / Critical), shades the cell
ADOWASPRRCThe same severity band, under its generic code identical to ADOWASP above
ADOWASPRRSThe composite score (used to break ties within a band)
ADOWASPRRLLikelihood, e.g. 6.25 (High)
ADOWASPRRIImpact, e.g. 7.00 (High)
ADOWASPRRVThe full OWASP-RR vector
ADOWASPRRCOMPEvery one of the sixteen factors and its rating
Tip
Both ADOWASP and ADOWASPRRC render the identical severity band use whichever reads more clearly in your template; there is no difference in output.

DREAD

Ordinal   Damage, Reproducibility, Exploitability, Affected users, Discoverability rated on sliders and aggregated. DREAD has no single canonical form, so PentOne ships three: the 0-10 mean (default, dread), the four-factor DREAD-D (dread-d), and the classic summed 5-50 (dread-sum). Switching aggregation changes the printed number but never the ordering.

CodeRenders
ADDREADThe composite DREAD score identical to ADDREADS below
ADDREADSThe composite DREAD score, under its generic code
ADDREADVThe DREAD vector (all five factors as one string)
ADDREADCSeverity band (shades the cell)
ADDREADBPer-factor breakdown, e.g. Damage 8 / Reproducibility 9 / …
ADDREADDM … ADDREADDIEach factor on its own (DM, RP, EX, AU, DI)
Tip
The variant forms register their own codes from their system name (e.g. DREAD-D produces ADDREADDS/ADDREADDC, DREAD-classic produces ADDREADSUMS/ADDREADSUMC). Pick one variant per report and stay consistent ADDREAD/ADDREADS always mean the default 0-10 mean form.

EPSS - Exploit Prediction Scoring System

Probability   The probability a vulnerability will be exploited in the wild in the next 30 days. It is not a severity a High EPSS on a Medium finding means “patch this first”. In ranking it multiplies the core risk rather than competing with it.

CodeRenders
ADEPSSThe raw probability (0-1). Add .PERC or .PCT to print it as a percentage
ADEPSSPProbability already formatted as a percentage, e.g. 32.4%
ADEPSSPCTPercentile rank against all scored CVEs, e.g. 97.1%
ADEPSSCThe band label (Very Low … Very High)
ADEPSSDATEThe date this EPSS score was published

SSVC - Stakeholder-Specific Vulnerability Categorization

Decision   CISA's decision tree. Answer four questions (Exploitation, Automatable, Technical Impact, Mission) and it returns an action, not a number. In ranking, an “Act” finding cannot sort below one marked “Track”. SSVC has no score placeholder inventing one would be a lie.

CodeRenders
ADSSVCThe decision Act / Attend / Track* / Track (shades the cell)
ADSSVCVThe four answers that produced the decision
ADSSVCEXP · ADSSVCAUTO · ADSSVCTI · ADSSVCMIEach input on its own line

STRIDE

Categorical   Microsoft's threat-type taxonomy: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege. It classifies a threat; it never scores. Pair it with a real severity framework for the number.

CodeRenders
ADSTRIDEThe threat category, e.g. Tampering
ADSTRIDEMThe security property it violates, e.g. Integrity protection

Reference taxonomies - CVE, KEV, CAPEC, ATT&CK

Categorical   Four identifier frameworks that never score the enterprise vulnerability-management fields security teams expect alongside a finding. Each takes a single ID and renders that ID's own published record.

FrameworkCodes
CVE a specific vulnerabilityADCVE · ADCVEDESC · ADCVEPUB · ADCVEMOD · ADCVEPROD · ADCVEREF · ADCVECWE · ADCVECVSS
KEV CISA known-exploitedADKEV · ADKEVDATE · ADKEVRANSOM · ADKEVWILD
CAPEC attack patternADCAPEC · ADCAPECNAME · ADCAPECSEV · ADCAPECFLOW · ADCAPECMIT
ATT&CK adversary techniqueADATTACK · ADATTACKNAME · ADATTACKTAC · ADATTACKDET · ADATTACKMIT
ID codes work immediately; descriptive text needs the catalog imported
ADCVE, ADCAPEC and ADATTACK render as soon as you enter an ID no catalog required. The descriptive textcodes (description, affected products, attack flow, detection guidance, mitigations, and so on) quote NVD's / CISA's / MITRE's own published wording directly, so they render blank until that real feed is imported into your workspace nothing is ever paraphrased from memory and passed off as an official record.
KEV is a closed list - it can correctly say No
ADKEV and ADKEVWILD need the CISA KEV catalog imported too but once it is, a CVE that genuinely is not on the list correctly renders No, not blank. Before import, both render blank rather than guessing an answer either way.

The legacy severity ladder

Ordinal   The classic PentOne severity {Critical, High, Medium, Low, Informational}. It is what a finding uses when nobody adopts anything fancier, and it has no dedicated codes of its own on purpose: ADCLR (coloured) and ADC (label only) already are its output. The field name severity resolves to this ladder.

Custom / proprietary frameworks

Any kind   A firm with its own house methodology, a client-mandated 0-100 matrix, or a five-colour ladder registers it once as configuration no code, no deploy. It immediately gains AD{NAME}S / AD{NAME}V / AD{NAME}C placeholders (e.g. an “acme-risk” framework gives ADACMERISKS, ADACMERISKV, ADACMERISKC), and the generic ADSCORE/ADVEC/ADBAND resolve to it too. Because every framework's severity bands are lined up on the same common scale (see Severity ordering), a custom 0-100 scale ranks correctly alongside CVSS in the same report.

Note
Every framework's codes are listed together on the Full reference page. The ordering page explains how they combine into one defensible order.

Severity ordering across frameworks

How PentOne orders findings when they are scored with different frameworks - and preserves severity across them.

Findings in a generated report are always ranked automatically, highest risk first. You cannot hand-order them. This page explains how that ranking works so the order in your report is never a surprise even when different findings are scored with different frameworks.

In short
PentOne combines every scoring framework a finding carries into one risk ranking. A framework's severity (CVSS, OWASP RR, DREAD…) contributes to the core ranking; a likelihood framework (EPSS) multiplies that ranking up or down; a decision framework (SSVC) can force a finding to the top regardless of its score. A finding with no score at all is never given a fake number it is placed honestly below every scored finding, not silently treated as harmless.

Why not just sort by CVSS score?

Because a real engagement is messier than one framework. Some findings have a CVSS vector, some carry only a CWE classification, a few have an EPSS exploitation-likelihood figure from a threat feed, the client mandates their own risk matrix, and the team ran SSVC on the ones that mattered most. All of that is real evidence and none of it is on the same scale. Sorting by CVSS alone throws away everything else and quietly ranks an unscored finding as if it were harmless which is the most dangerous possible default for a security report.

How the ranking is built

StepWhat happensWhy it matters
Put every framework on the same scaleEach severity framework's score is mapped onto a common 0-1 scale using its own severity bands not by dividing by its maximumMakes CVSS (0-10), OWASP RR (0-9) and a client's own 0-100 matrix genuinely comparable
Combine the severity opinionsIf a finding has more than one severity framework, they combine weighted by how strong each one isA validated CVSS vector counts for more than a severity picked from a dropdown
Let EPSS amplify the resultAn exploitation-likelihood score multiplies the combined severity up, not downA Medium that is actively being exploited outranks a High nobody can reach - the entire reason EPSS exists
Let SSVC set a floorAn "Act" decision cannot be ranked below a "Track" one, no matter what the numbers sayA prioritisation verdict is meant to override raw numbers, not average against them
Place the unscored honestlyA finding with no score of any kind is ranked below every scored finding never given an invented numberHonest absence beats a number nobody can defend

Severity is preserved across frameworks

This is the property the whole design exists for: because every framework's severity bands are mapped onto the same scale, the bottom of any framework's “Critical” band lands in the same place. A finding rated Critical on a client's bespoke 0-100 matrix and one rated 9.8 in CVSS sit next to each other correctly neither framework gets an unfair advantage just because its scale happens to be bigger or smaller.

The primary framework
If your workspace sets a primary scoring framework, that framework's opinion drives the ranking directly and every other framework on a finding becomes a tiebreak instead of being blended in because a client who mandates their own matrix does not want it averaged away with CVSS.

The order is stable

The final order is fully deterministic every finding gets an exact position, with the finding's own id as the final tiebreak so nothing is ever ambiguous. The same findings always produce the same report order, so regenerating a report never silently reshuffles it between runs.

✓ Good practice
Score findings with whatever frameworks genuinely fit CVSS where you have a vector, CWE where you only have a weakness class, EPSS or SSVC where you have that data. The ranking uses everything you give it, and adding EPSS is what lets an actively-exploited Medium correctly outrank a theoretical High.
✗ Bad practice
Don't leave a genuinely serious finding unscored to try to “force” its position it drops below every scored finding, not above them. Don't expect switching a DREAD variant (summed vs. averaged) to change the order; it changes the printed number, never the ranking.
05

Formatting & output

Colors, rich content, the table of contents, and file formats.

Colors, evidence & signatures

Severity colors, evidence blocks, and signatures.

Severity colors (ADCLR)

Use ADCLR on a severity value inside a table cell to color the cell background by severity:

Note
Use ADCLR for the colored cell. Use ADC for the label without a colored background.

Evidence & Proof of Concept (ADBLOCK)

Use ADBLOCK for any finding section that needs the block editor the same Notion-like editor you use when filling findings in PentOne. It supports headings, paragraphs, bullet & numbered lists, tables, code blocks, and images all mixed together in one flow.

Proof of Concept:
{{vulnerability.proof-of-concept.ADBLOCK}}
Use ADBLOCK for PoC and image attachments
Any report area that needs screenshots, tables, code, payloads, or mixed evidence should use ADBLOCK place it inside the /// section so each finding renders its own block. Attach images inside the block editor field on the finding, not as a separate placeholder.

Narrative text (ADBLTN)

Use ADBLTN when the section is text only paragraphs, headings, bullet lists, numbered lists. No images, no tables, no code blocks.

{{vulnerability.description.ADBLTN}}   Description / narrative
{{vulnerability.impact.ADBLTN}}          Business impact
{{vulnerability.remediation.ADBLTN}}     Fix guidance (text + lists)
Tip
If you only need headings, bullets and paragraphs, ADBLTN is enough. Use ADBLOCK when screenshots, tables, or code belong in that section.

What the block editor produces in your Word document

Content typed in the block editor (on the finding form, not in your template) renders as real, native Word elements not typed-out text imitating them. This matters because it means the generated report is fully editable afterward, exactly like something a person built by hand in Word.

Block typeRenders as
HeadingThe template's own Heading 1/2/3 style when the template defines one, or a bold + larger fallback when it doesn't
Bullet / numbered listA native Word list real numbering, continuable and restyleable from the Word ribbon, not typed "1." or "•" characters
TableA genuine Word table with real cells and borders, even if the template defines no table style
ImageAn embedded image, optionally with a caption and left / center / right alignment both carry through to the generated report
Code blockMonospace text on a shaded background
Image captions and alignment
When attaching an image in the block editor, you can set a caption and choose left, center, or right alignment both carry through to the generated report exactly as set.

Signatures (SIG) & dates

{{project.reviewer-signature.SIG}}   Sign-off block (image or text)
{{report.export-date.DATE.AUTO}}     Today's date, automatic
{{project.start-date.DATE}}          A date you entered

All dates print as YYYY-MM-DD.

Table of contents & pages

Control the table of contents and page breaks.

Table of contents

Put this placeholder exactly where you want the table of contents to appear. PentOne builds a clickable TOC from your headings at that spot.

{{toc.table-of-contents.AUTO}}
Tip
Always use the placeholder to control placement. PentOne can fall back to detecting a “Table of Contents” heading, but that gives you less control.

Page breaks

Start a new page with either a line containing only ---, or an HTML page break. Use these to keep the cover, executive summary, and findings on separate pages.

---
<div style="page-break-after: always;"></div>

File & output formats

Accepted uploads and available report downloads.

Templates must be DOCX, up to 10 MB. Every generated report can be downloaded as DOCX or PDF.

FormatRoleNotes
DOCXTemplate upload (only supported format)Full formatting, tables, images, colors. Use .docx, not .doc.
DOCX / PDFReport downloadEvery generated report is available in both.
Tip
Design your template in Microsoft Word and save as .docx other formats are not supported for upload.
06

Examples & reference

Complete templates to copy, and every placeholder on one page.

Full example templates

Complete copy-paste templates to start from - a simple report and a full multi-framework enterprise report.

Copy-paste, complete templates. Start with the Quickstart, then graduate to this one.

Executive summary + findings table + detail sections

report-template.docx
PENETRATION TEST REPORT

Prepared for: {{project.client-name.TXT}}
Prepared by:  {{project.lead-assessor.TXT}}
Date:         {{report.export-date.DATE.AUTO}}

---

1. EXECUTIVE SUMMARY

| Severity | Count |
|----------|-------|
| Critical | {{critical.sum}} |
| High     | {{high.sum}} |
| Medium   | {{medium.sum}} |
| Low      | {{low.sum}} |
| Info     | {{info.sum}} |

2. FINDINGS OVERVIEW

| # | Finding | Severity | CVSS |
|---|---------|----------|------|
| {{number.serial-no.TBL1.CLM1.MLTIRW.AUTO}} | {{vulnerability.title.TXT.TBL1.CLM2.MLTIRW}} | {{vulnerability.severity.ADCLR.TBL1.CLM3.MLTIRW}} | {{vulnerability.cvss-score.ADCVSSS.TBL1.CLM4.MLTIRW}} |

---

3. DETAILED FINDINGS

///
{{vulnerability.title.BOLD.TXT}}

| Severity | CVSS |
|----------|------|
| {{vulnerability.severity.ADCLR}} | {{vulnerability.cvss-score.ADCVSSS}} |

Description:
{{vulnerability.description.ADBLTN}}

Impact:
{{vulnerability.impact.ADBLTN}}

Proof of Concept:
{{vulnerability.proof-of-concept.ADBLOCK}}

Remediation:
{{vulnerability.remediation.ADBLTN}}
///
For an enterprise report
Add a cover page (logo, {{project.client-name.TXT}}, date, then ---), a TOC page ({{toc.table-of-contents.AUTO}}), a scope table using project.* multi-row fields with TBL2, a PoC/evidence block per finding ({{vulnerability.proof-of-concept.ADBLOCK}}), and a sign-off block ({{project.reviewer-signature.SIG}}).

A multi-framework finding block

When findings carry more than CVSS, a detail block can present every framework side by side. Everything here resolves per finding because it sits inside the /// markers each placeholder simply renders blank on a finding that wasn't scored with that framework.

rich finding block
///
{{vulnerability.title.BOLD.TXT}}

| Severity | CVSS | CWE | EPSS | SSVC |
|----------|------|-----|------|------|
| {{vulnerability.severity.ADCLR}} | {{vulnerability.cvss-score.ADCVSSS}} | {{vulnerability.cwe-id.ADCWE}} | {{vulnerability.epss.ADEPSSP}} | {{vulnerability.ssvc.ADSSVC}} |

CVSS vector: {{vulnerability.cvss-vector.ADCVSSV}}
Weakness:    {{vulnerability.cwe-id.ADCWEL}}

Description:
{{vulnerability.description.ADBLTN}}

Proof of Concept:
{{vulnerability.proof-of-concept.ADBLOCK}}

Remediation:
{{vulnerability.remediation.ADBLTN}}
///
Note
Pick the frameworks your team actually fills in. There is no penalty for placing a code the finding doesn't use it just leaves that cell empty rather than printing a leftover placeholder.
07

Help & reference

Common mistakes, what is not supported, and how to fix problems.

The #1 problem in Word

Why Word silently breaks placeholders - and how to avoid it.

This causes more failures than anything else
Microsoft Word stores text in pieces called runs. Anything that touches part of a placeholder a spellcheck squiggle, autocorrect, changing formatting mid-word, even pausing while typing can silently split {{vulnerability.title.TXT}} into {{vulnerability. + title + .TXT}}. It looks identical to you, but the engine can no longer read it.

How to avoid it

  • Type the whole placeholder in one continuous action, then move on. Don't format individual parts.
  • If you must format, select the entire placeholder (from {{ to }}) and format it all at once.
  • Safest method: type placeholders in Notepad first, then paste into Word as plain text (Ctrl+Shift+V).
  • If one isn't working, delete it entirely and retype it in one go don't fix the middle.
  • Turn off autocorrect if it keeps “correcting” your dots or dashes.
Note
PentOne works hard to re-stitch split placeholders automatically and usually succeeds but keeping each placeholder in one clean run is the guaranteed fix.

Troubleshooting

Symptoms, causes, and fixes for common template problems.

SymptomLikely causeFix
Placeholder is blankField name mismatch, or no data enteredCheck the exact field name; try hyphen vs underscore; make sure a value exists
{{…}} survives into the reportWord split it, or a typoSee the #1 problem; retype it cleanly
/// section doesn’t repeatMissing a marker, or not on its own lineEnsure two /// lines, each alone, wrapping the section
Table rows don’t multiplyMissing .MLTIRW or mismatched TBL/CLMAdd .MLTIRW; one TBL per table; match CLM to column order
Severity has no colorUsed ADC instead of ADCLR, or not in a cellUse ADCLR, inside a table cell
Score / severity is blankThe finding was never scored with that frameworkPentOne never invents a score. Score the finding, or use a framework it actually carries. See How scoring works
A score placeholder shows a "{…}" blobA multi-factor framework was stored under one combined fieldSubmit each factor as its own field so an assessment is built (DREAD, OWASP, SSVC)
Findings in unexpected orderRanking is automatic, combining every framework each finding carriesIntentional check each finding's scores. See Severity ordering
Image missing in PoC/evidenceUsed ADBLTN instead of ADBLOCK, or content not savedUse ADBLOCK for image sections; attach images in the block editor field
{{critical.percentage}} shows nothingPercentages aren’t supportedUse {{critical.sum}}; compute percentages manually

What is NOT supported

Syntax that parses but never renders - avoid these.

Avoid these they produce empty or broken output
These look like they should work some even pass the template checker but the report generator does not fill them in.
Don't useWhyUse instead
{{critical.percentage}}Percentages are parsed but never calculated{{critical.sum}}
{{#if}} … {{/if}}Conditionals are recognized but not renderedStructure without conditionals
{{#each}} … {{/each}}Loops use /// and .MLTIRW, not #eachUse /// sections
{{!-- comment --}}Comments aren't processedDelete notes before generating
CALC, TABLE, REFNo dedicated renderingA supported type code
.N array formatLegacy; still tolerated but deprecatedPrefer /// sections and .MLTIRW
{{ with spaces }}Spaces break parsingUse - or _

Full reference

Every placeholder, type code, and marker on one page.

Placeholder reference

PlaceholderPurposeRepeats?Output
{{project.<field>.TXT}}Any project fieldnotext
{{report.export-date.DATE.AUTO}}Today's datenoYYYY-MM-DD
{{critical.sum}} … {{info.sum}}Count by severitynonumber
{{vulnerability.title.BOLD.TXT}}Finding title, boldyesbold text
{{vulnerability.severity.ADCLR}}Severity, colored cellyescolored cell
{{vulnerability.description.ADBLTN}}Descriptionyesrich text
{{vulnerability.proof-of-concept.ADBLOCK}}Evidenceyescode block
{{vulnerability.proof-of-concept.ADBLOCK}}PoC / evidence (block editor)yesimages, code, mixed
{{number.serial-no.TBL1.CLM1.MLTIRW.AUTO}}Auto row numberyes1, 2, 3…
{{toc.table-of-contents.AUTO}}Table of contentsnoTOC

Structural markers

MarkerMeaning
/// … ///Repeat the enclosed section once per finding
.MLTIRWRepeat a table row once per finding / project-list item
.TBL{n}Table number
.CLM{n}Column number
.AUTOAuto value (today's date / running number)
---Page break

Scoring & severity codes

The full scoring vocabulary, by framework. See How scoring works for the model and Every scoring framework for what each renders.

FrameworkKindType codes
GenericanyADSCORE · ADVEC · ADBAND
CVSS 3.1 / 3.0ordinalADCVSSS · ADCVSSV · ADCLR · ADC · ADCVSSREV · ADCVSSBASE · ADCVSSTEMP · ADCVSSENVS · ADCVSSB* · ADCVSST* · ADCVSSR* · ADCVSSE*
CVSS 4.0ordinalADCVSS40S · ADCVSS40V · ADCVSS40C · ADCVSS40AV … ADCVSS40SA (11 base metrics)
CWEordinal / categoricalADCWE · ADCWEL · ADCWES · ADCWEC · ADCWEV · ADCWEN · ADCWECAT · ADCWEABS · ADCWEDESC · ADCWEEXT · ADCWEPLAT · ADCWEMOI · ADCWECONS · ADCWEDET · ADCWEMIT · ADCWEREL · ADCWECAPEC
OWASP RRordinalADOWASP · ADOWASPRRS · ADOWASPRRV · ADOWASPRRC · ADOWASPRRL · ADOWASPRRI · ADOWASPRRCOMP
DREADordinalADDREAD · ADDREADS · ADDREADV · ADDREADC · ADDREADB · ADDREADDM · ADDREADRP · ADDREADEX · ADDREADAU · ADDREADDI
EPSSprobabilityADEPSS · ADEPSSP · ADEPSSPCT · ADEPSSC · ADEPSSDATE
SSVCdecisionADSSVC · ADSSVCV · ADSSVCEXP · ADSSVCAUTO · ADSSVCTI · ADSSVCMI
STRIDEcategoricalADSTRIDE · ADSTRIDEM
CVEcategoricalADCVE · ADCVEDESC · ADCVEPUB · ADCVEMOD · ADCVEPROD · ADCVEREF · ADCVECWE · ADCVECVSS
KEVcategoricalADKEV · ADKEVDATE · ADKEVRANSOM · ADKEVWILD
CAPECcategoricalADCAPEC · ADCAPECNAME · ADCAPECSEV · ADCAPECFLOW · ADCAPECMIT
ATT&CKcategoricalADATTACK · ADATTACKNAME · ADATTACKTAC · ADATTACKDET · ADATTACKMIT
Legacy ladderordinalADCLR · ADC (no dedicated codes by design)
CustomanyAD{NAME}S · AD{NAME}V · AD{NAME}C
Scoring modifierOnEffect
.ALLADCWERender every CWE id, not just the primary
.TXT / .LABELADCWERender the full CWE label (id + name)
.PERC / .PCTADEPSSPrint the probability as a percentage
a framework nameADSCORE / ADVEC / ADBANDPin the framework, e.g. {{vulnerability.risk.ADSCORE.CVSS}}
Two rules to remember for every scoring code above
  • For every dedicated code (ADCWE*, ADEPSS*, ADDREAD*, ADSSVC*, ADOWASP*, and so on) the field-name segment is not read only the type code determines what renders. Full explanation: Every scoring framework.
  • DREAD, SSVC, OWASP Risk Rating and EPSS each need their factors filled in as separate flat fields with exact names (e.g. DREAD needs damage, reproducibility, exploitability, affected_users, discoverability as five fields, not one). Full field-name tables: Every scoring framework.

Need a hand building your template?

Our team can convert an existing report into a reusable PentOne template.

Contact support