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.
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.
Client: {{project.client-name.TXT}}Client: Acme CorporationWhy 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.
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:
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.
Paste this into Microsoft Word
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}} ///
Save as a .docx file
.docx, not .doc.Upload it
Generate
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:
- Field names are fully dynamic use whatever you named the field (
client-name,CLIENT-NAME,client_nameare 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.
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
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.
- For a repeating target list (many rows), use
project.*with.MLTIRWe.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}}. NoTBL,CLM, orMLTIRWneeded. - 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
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
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)
TBL/CLM/MLTIRW entirely: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
numberis 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 asproject.client-name; nothing is hard-reserved about the name. - Add
.AUTOso 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}}.
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)
Choosing the right smart type
ADBLOCK not ADBLTN. ADBLTN is enough when you only need paragraphs and lists.Plain types (they print the value as text)
YYYY-MM-DD (e.g. 2026-07-06). That format is fixed restyle in Word after generating if you need a different look.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..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.
.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
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?
.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.
What .AUTO is NOT
- Do not add
.AUTOto regular fields like{{project.client-name.TXT.AUTO}}it will not auto-fill client names. DATEalone is a date you enter ({{project.start-date.DATE}}).DATE.AUTOis 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.
Custom field "engagement-code"{{project.engagement-code.TXT}}The naming rules (these matter)
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.
/// {{vulnerability.title.BOLD.TXT}} Severity: {{vulnerability.severity.ADCLR}} Description: {{vulnerability.description.ADBLTN}} ///
/// (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):
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.../// on its own line. Keep every vulnerability.* placeholder between the markers./// 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.).
- 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. NoTBL,CLM, orMLTIRW. - Same logic for
project.*, and for any non-repeating table cell in the document.
- 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
{{ vulnerability . title . TXT . TBL1 . CLM2 . MLTIRW }} scope field type table# col# repeat tag
Build a normal table in Word
Put MLTIRW placeholders in that single data row
TBL number; CLM matches column order.Example A Findings table (TBL1, vulnerability scope)
| # | 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)
| # | 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
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}} |
{{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.- One data row per table no extra blank rows.
- Same
TBLnumber for every placeholder in the same table. - New
TBLnumber for each separate repeating table. numberscope + any field name +.AUTOis for the#column onlyserial-noin examples is just a demo name.
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.
CVSS {{vulnerability.cvss-score.ADCVSSS}} / {{vulnerability.cwe-id.ADCWE}}CVSS 9.8 / CWE-89: SQL InjectionThe 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:
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
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:
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.ADCVSSS, ADCWE, ADEPSS). Keep every score placeholder inside a /// finding section or a MLTIRW row so it resolves against a specific finding.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
Severity: {{vulnerability.severity.ADCLR}} CVSS: {{vulnerability.cvss-score.ADCVSSS}} Vector: {{vulnerability.cvss-vector.ADCVSSV}}
Versions: 3.1, 3.0 and 4.0
- CVSS 3.1 is the default.
ADCVSSS/ADCVSSV/ADCLRresolve 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/ADCLRcodes 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”.
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:
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.
{{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.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.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.
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.
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.
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.
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.
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.
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.
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.
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.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.
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.
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
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 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.
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:
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}}
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)
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.
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}}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.
.docx other formats are not supported for upload.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
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}} ///
{{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.
/// {{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}} ///
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.
{{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.
Troubleshooting
Symptoms, causes, and fixes for common template problems.
What is NOT supported
Syntax that parses but never renders - avoid these.
Full reference
Every placeholder, type code, and marker on one page.
Placeholder reference
Structural markers
Scoring & severity codes
The full scoring vocabulary, by framework. See How scoring works for the model and Every scoring framework for what each renders.
- 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,discoverabilityas 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.