Support
Types of Reports

Custom Reports (Invicti Standard)

This document is for:
Invicti Standard

Invicti Standard allows you to create and define your own web security scan report templates. They can be used to generate custom reports that suit your business needs and for integration with other software applications.

There are two ways to create custom reports:

  •  You can create a new report template based on the existing templates via Invicti Standard UI.
  • Alternatively, you can create a report template by using the code below and save this file under C:\Users\[Username]\Documents\Invicti\Resources\Report Templates.
How to Create a New Report Template in Invicti Standard
  1. Open Invicti Standard.
  2. From the ribbon, select the File tab. Local Scans are displayed. Double-click the relevant scan to display its results. (This will be the first scan you want to add to the report.)
  3. From the Reporting tab, click New Report Template. The New Report Template dialog box is displayed.

  1. Select a Base Template, and enter a Name.

  1. Click OK to create the new report template. The created template file will be saved under C:\Users\[Username]\Documents\Invicti\Resources\Report Templates

  1. Use this report template to generate your custom report.

If you want to further modify this report, you can use a text editor to open the file and modify it.

How to Delete a Report Template from the Dashboard

Once created, the custom report appears on Invicti Standard UI under the Reporting tab. If you wish to delete the custom report from the UI, follow these steps to delete it:

  1. Go to C:\Users\[Username]\Documents\Invicti\Resources\Report Templates (stored in this file by default).
  2. Right-click the template you wish to delete, and click Delete.
  3. To remove it from the UI, a restart is required.

In addition to the New Report Template, you can copy and paste the code below to create your own report. The custom reporting tool employs the Razor templating engine that runs C# code to generate reports.

How to Create a Custom Web Security Scan Report
  1. Copy the code below to a text editor.
  2. Make the necessary changes on the code.
  3. Save this template to C:\Users\[Username]\Documents\Invicti\Resources\Report Templates.
  4. Reports can be exported now.

In Invicti Standard, when naming your custom template, the name should take the form of ‘Name.html’ and have the file extension ‘cshtml’. This will enable Invicti Standard to recognize it as a custom report template.

Code Example for Custom Invicti Standard Report

Invicti’s scripting language is C#. Below is a sample code for a web security report that generates an XML file which includes the following:

  • A list of all the vulnerabilities detected during the scan
  • The vulnerable Parameter and request method (GET/POST)
  • Vulnerability Details
  • Confirmation Status
  • Extra exploitation data
  • Web security scan time
  • Vulnerability severity

You can add more details into the reports, customize them, or filter your reports with custom criteria.

This is a sample of the code that could be used to create a custom Invicti Standard report.

@using System
@using System.Collections.Generic
@using System.Globalization
@using System.IO
@using System.Linq
@using MSL.Common.Text;
@using MSL.Core.Configuration
@using MSL.Core.Data.Resources
@using MSL.Core.Entities.Cvss
@using MSL.Core.Entities.Vulnerability
@using MSL.Core.Process.Exploitation
@using MSL.Core.Process.Reporting;
@using MSL.Core.Process.Reporting.Cvss
@model MSL.Core.Reporting.Model.GenericXmlReportModel
<?xml version="1.0" encoding="utf-8" ?>
@if(Model.AddXsl)
{
    <?xml-stylesheet href="vulnerabilities-list.xsl" type="text/xsl" ?>
}
<netsparker generated="@DateTime.Now.ToString(CultureInfo.InvariantCulture)">
    <target>
        <url>@ReportingUtility.XmlShortEscape(Model.ScanResult.Brief.Link)</url>
        <scantime>@Convert.ToInt32(Model.ScanResult.Brief.ScanDuration.TotalSeconds)</scantime>
    </target>
    @{

    foreach (var vulnerability in Model.ScanResult.Vulnerabilities)
    {

        <vulnerability confirmed="@vulnerability.IsConfirmed.ToString()">
            <url>@ReportingUtility.XmlShortEscape(vulnerability.Request.Url)</url>
            <type>@vulnerability.Profile.Type.ToString()</type>
            <severity>@vulnerability.Profile.Severity.ToString()</severity>
            @if (!vulnerability.IsConfirmed)
            {
                <certainty>@vulnerability.Certainty</certainty>
            }
            @if (vulnerability.Request.Parameters.Any(x => x.IsAttackParameter))
            {
                var attackParameter = vulnerability.Request.Parameters.First(x => x.IsAttackParameter);

                <vulnerableparametertype>@ReportingUtility.XmlShortEscape(attackParameter.TypeName)</vulnerableparametertype>
                <vulnerableparameter>@ReportingUtility.XmlShortEscape(attackParameter.Name)</vulnerableparameter>
                <vulnerableparametervalue>@ReportingUtility.XmlShortEscape(attackParameter.Value)</vulnerableparametervalue>
            }
            <rawrequest><![CDATA[@Raw(vulnerability.Request.Full.ToString())]]></rawrequest>
            @if (vulnerability.Request.InjectionRaw != null)
            {
                <injectionrequest>@Raw(ReportingUtility.XmlEscapeCharacterData(vulnerability.Request.InjectionRaw.ToString()))</injectionrequest>
            }
            <rawresponse>@Raw(ReportingUtility.XmlEscapeCharacterData(vulnerability.Response.Full.ToString()))</rawresponse>
            @if (vulnerability.Response.InjectionRaw != null)
            {
                <injectionresponse>@Raw(ReportingUtility.XmlEscapeCharacterData(vulnerability.Response.InjectionRaw.ToString()))</injectionresponse>
            }
            <extrainformation>
                @foreach (var field in vulnerability.CustomFields)
                {
                    <info name="@field.Name">@Raw(ReportingUtility.XmlEscapeCharacterData(string.Join(", ", field.Values)))</info>
                }
            </extrainformation>
            <proofs>@Raw(vulnerability.CustomData.ToString())</proofs>

            @if (vulnerability.Profile.Template.Classifications.Any())
            {
                <classification>
                    @foreach (var classification in vulnerability.Profile.Template.Classifications)
                    {
                        var tagName = classification.Group.ToString().ToUpperInvariant();
                        @Raw(string.Format("<{0}>{1}</{0}>", tagName, classification.Value))
                    }
                    @foreach (var score in vulnerability.Profile.Template.CvssScores)
                    {
                        var cvssScore = score.Value;
                        <CVSS>
                            <vector>@score.Key</vector>

                            <score>
                                <type>Base</type>
                                <value>@cvssScore.Base.Value.ToString("0.0", CultureInfo.InvariantCulture)</value>
                                <severity>@cvssScore.Base.Severity</severity>
                            </score>
                            <score>
                                <type>Temporal</type>
                                <value>@cvssScore.Temporal.Value.ToString("0.0", CultureInfo.InvariantCulture)</value>
                                <severity>@cvssScore.Temporal.Severity</severity>
                            </score>
                            <score>
                                <type>Environmental</type>
                                <value>@cvssScore.Environmental.Value.ToString("0.0", CultureInfo.InvariantCulture)</value>
                                <severity>@cvssScore.Environmental.Severity</severity>
                            </score>

                        </CVSS>
                    }
                </classification>
            }

            @if (vulnerability.Profile.Template.VersionVulnerabilities.Any())
            {
                <knownvulnerabilities>
                    @foreach (var implied in vulnerability.Profile.Template.VersionVulnerabilities)
                    {
                        <knownvulnerability>
                            <title>@implied.Title</title>
                            <severity>@implied.Severity</severity>
                            <references>@(implied.References == null ? string.Empty : implied.References.Trim())</references>                            <references>@(implied.Bdu == null ? string.Empty : implied.Bdu.Trim())</references>
                            <affectedversions>@implied.AffectedVersions</affectedversions>
                        </knownvulnerability>
                    }
                </knownvulnerabilities>
            }
        </vulnerability>

    }
    }
</netsparker>

Saving the Custom Report Template

Every time you create a new custom report template, save it into the default directory. This directory is in the Resources sub-directory of the Invicti data directory. The default location is the current Windows user’s Documents/My Documents directory. The full path of that directory would be Documents/Invicti/Resources/Report Templates.

During startup, the Invicti Standard scanner scans the Report Templates directory for C# template files (*.cshtml).  If the scanner detects a new file in this folder, it will be displayed on the Reporting tab as a custom report.

Defining the File Type (Extension) of the Custom Web Security Report

The name of the file will be visible under the Reporting menu. When selected, the generated report will use the extension from the custom report file name. The file extension should be chosen based on the content type of the report. For the sample report above, it should be XML.

For example:

  • “Vulnerabilities List (XML).xml.cshtml” – File extension will be “XML”
  • “Vulnerabilities List as Web Page.html.cshtml” – File extension will be “HTML”

Testing the Custom Reports

You do not need to restart Invicti Standard every time you change the source code of your custom report. However, if you want to change the base template you selected while creating your custom report via UI, you cannot do this. It is better to create a new custom report with your desired base template. When you create a new template, you have to restart Invicti Standard in order for this change to take effect. Once Invicti adds the custom report to the Reporting tab, all you need to do is run it. If it fails to compile, an error message will be displayed.

Security of Custom Reports

The Reporting engine runs with current user's privileges. Don't run the report unless you trust its author.

Comprehensive API Documentation

For further information on API Settings, from the Help menu in Invicti Standard, click Reporting API to see our MSDN-style API documentation that is updated with each relevant code change.