Export templates use a JSON schema to define what entities and entity fields to include in the export. A template in its simplest form will export data directly from the template's selected entity type. The following examples come from a template with a Finding Entity type. Parameter name will be the name of the parameter on each Finding object to use and key is the title of that column in the output.
Output | Syntax |
---|---|
CSV | { sheets: [{ sheetName: 'Findings', template: [{ key: 'Finding Name', parameterName: 'name' }, { key: 'Severity', parameterName: 'severity' }] }] } Multiple sheets can be added to the excel document by adding additional objects in the sheets array. |
JSON | { template: [{ key: 'finding_name', parameterName: 'name' }, { key: 'severity', parameterName: 'severity' }] } |
XML | { getRootDocument: () => { var doc = document.implementation.createDocument("", "", null); var rootElem = doc.createElement("vulnerabilities"); rootElem.setAttribute('xmlns:xsd','http://www.w3.org/2001/XMLSchema') rootElem.setAttribute('xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance'); doc.appendChild(rootElem); return doc; }, elementName: 'vulnerablity', template: [{ key: 'name', xmlLocation: 'body', parameterName: 'name' }, { key: 'severity', xmlLocation: 'attribute', parameterName: 'severity' }] }
|
Advanced template formats are also available for using more nested forms of data. The following templateTypes are available:
Template Type | Description |
---|---|
findingsByMasterFinding | A nested hierarchy that allows the following scopes:
|
findings | A nested hierarchy that allows the following scopes:
|
Template Scopes
When using a template type that allows iterating through nested objects, the scope determines when to stop iterating. For example, with the findingsByMasterFinding template the furthest level of iteration (scope) is an instance. In some cases it may be beneficial to stop at the Finding level and ignore instances. A template for that would look like the following:
{ templateType: 'findingsByMasterFinding', templateScope: 'finding', template: [{ key: 'Finding Name', location: 'finding', parameterName: 'name' }, { key: 'Severity', location: 'finding', parameterName: 'severity' }] }
In the above, a location parameter is also included, this denotes which entity to get data from. A template type of findingsByMasterFinding with a scope of finding, can use locations of both masterFinding or finding. Instance is not a viable location because the scope is set to stop at finding.
Static Parameters
A static parameter can be added so that no matter what data is received, the same value will always be used.
{ template: [{ key: 'Finding Name', parameterName: 'name' }, { key: 'Severity', parameterName: 'severity' }, { key: 'Company', static: 'NetSPI' }] }
Transform Functions
Sometimes additional logic will need to be performed for any given piece of data. The transform function allows arbitrary javascript to be included to transform/aggregate data. A simple transform looks like:
{ template: [{ key: 'Finding Name', parameterName: 'name' }, { key: 'Severity', parameterName: 'severity' }, { key: 'Math Example', transform: ()=>{ return 1+1; } }] }
Transforms are best suited when complex operations, transformations, or aggregations need to be performed. The transform will always be given 3 parameters:
- data
- For non-scoped templates this represents all data for the current entity
- For scoped templates this will be an object with a parameter for each scope in the templateType
- util
- A util function. This is a placeholder for future operations that may require complex logic not suited for templates.
- globalData
- Global data represents all data gotten for this template. The below tables identify which global data is available for each entity type
An advanced transform may be a scenario where the template wants to list all findings, with a count of their instances. The following will achieve that:
{ templateType: 'findingsByMasterFinding', templateScope: 'finding', template: [{ key: 'Finding Name', location: 'finding', parameterName: 'name' }, { key: 'Severity', location: 'finding', parameterName: 'severity' }, { key: 'Instance Count', transform: (data)=>{ return data.finding.instances.length; } }] }
Since this is a scope template the data object contains a finding property and a masterFinding property. We access the data object's finding property and then get the length of the instances array.
Transforms can also be performed at the template level, the first parameter being the string representation of either the completed JSON, CSV, or XML data your template. The data should be returned as a string once transformations have been completed.
{ templateType: 'findingsByMasterFinding', templateScope: 'finding', transformOutput: (data) => { let parsedData = JSON.parse(data).map((finding)=>{return finding.name='Replaced'}); return JSON.stringify(parsedData); }, template: [{ key: 'Finding Name', location: 'finding', parameterName: 'name' }, { key: 'Severity', location: 'finding', parameterName: 'severity' }] }
Outlined below are all fields available for each supported Entity template type, any non-standard fields are included inline. To see which data each entity always contains, please view Entity Fields. For each entity template type the following fields will also all be available on the globalData parameter in the transform function.
Field | Description |
---|---|
project | No non-standard fields. Only available for single record templates. |
projects | No non-standard fields. Only available for multiple record templates. |
findings |
|
instances |
|
verifications | No non-standard fields |
assets |
|
Field | Description |
---|---|
assets | No non-standard fields |
Field | Description |
---|---|
applications | No non-standard fields |
Field | Description |
---|---|
scans | No non-standard fields |
Field | Description |
---|---|
users | No non-standard fields |
Field | Description |
---|---|
findings |
|
instances | No non-standard fields |
For assistance on creating and customizing export templates, contact NetSPI.