csaf-tool 0.3.2
CSAF generator and analyser
License: MIT
Requires Python: >=3.7
Keywords: security, tools, CSAF, CSAF 2.0, VexDevSecOps, vulnerabilities

# CSAF-Tool

The CSAF-Tool generates a [CSAF 2.0 file](https://www.csaf.io) including product tree and vulnerabilities associated with products
specified in the product tree. It can also be used to generate a human-readable output of a CSAF document.

## Installation

To install use the following command:

`pip install csaf-tool`

Alternatively, just clone the repo and install dependencies using the following command:

`pip install -U -r requirements.txt`

The tool requires Python 3 (3.7+). It is recommended to use a virtual python environment especially
if you are using different versions of python. `virtualenv` is a tool for setting up virtual python environments which
allows you to have all the dependencies for the tool set up in a single environment, or have different environments set
up for testing using different versions of Python.

## Usage

```
usage: csaf-tool [-h] [-g] [-i INPUT_FILE] [-p PRODUCT] [-v VULNERABILITIES] [-t TITLE] [--header HEADER] [--id ID] [-C CONFIG] [-o OUTPUT_FILE] [-V]

CSAF-tool generates a CSAF 2.0 file including product tree and vulnerabilities associated with products specified in the product tree.

options:
  -h, --help            show this help message and exit
  -C CONFIG, --config CONFIG
                        name of config file
  -V, --version         show program's version number and exit

Input:
  -g, --generate        generate CSAF file
  -i INPUT_FILE, --input-file INPUT_FILE
                        CSAF filename to be analysed
  -p PRODUCT, --product PRODUCT
                        product tree
  -v VULNERABILITIES, --vulnerabilities VULNERABILITIES
                        list of vulnerabilities
  -t TITLE, --title TITLE
                        CSAF title
  --header HEADER       CSAF heading
  --id ID               CSAF document identifier


Output:
  -o OUTPUT_FILE, --output-file OUTPUT_FILE
                        CSAF filename
```

## Operation

The CSAF tool can be used as a command line tool to generate or analyse a CSAF document. It can also be used as a Python library
to programmatically generate a CSAF document.

### CSAF Generation using command line

The `--generate` option is used to indicate that a CSAF file is to be produced.

The following parameters are mandatory:

1. The `--product` option is used to specify the products to be included in the CSAF product tree. The file
is a CSV file and consists of one entry per line per product which specifies the product name, the name of the vendor and the release.
Multiple releases of a product should be specified as separate entries. The first line of the file contains the
header `product,vendor,release`. The following is an example product file.

```
product,vendor,release
product_1,AVendor,1.1
product_1,AVendor,1.2
product_1,AVendor,2.0
product_2,AVendor1,1
product_3,AVendor,2022H2

```

2. The `--vulnerabilities` option is used to specify the vulnerabilities to be included in the CSAF document. The file
is a CSV file and consists of one entry per line per vulnerability which specifies the product name, the release of the product,
the identity of the vulnerability (e.g. CVE number), a brief description of the vulnerability, the status of the vulnerability (one of
"mitigation", "no_fix_planned", "none_available", "vendor_fix" or "workaround") and an associated comment. Multiple vulnerabilities for a product should be specified as separate entries. The first line of the file contains the
header `product,release,id,description,status,comment`. The following is an example vulnerabilities file.

```
product,release,id,description,status,comment
product_1,1.1,CVE-2020-1234,This is a simple description,vendor_fix,Customers should upgrade to the latest version of the product
product_1,1.1,CVE-2020-9876,This is another vulnerabilty description,none_available,Still under investigation
```

3. The `--output-file` option is used to specify the filename for the generated CSAF document.

The `--header` option is used to specify a title for the document generated by the tool. It is recommended that this is
sufficiently unique to distinguish it from similar documents.

The `--title` option is used to provide a brief summary note of the document generated by the tool.

The `--id` option is used to provide a unique document identifier for the document. If this is not provided a default
identifier of _**CSAF-Document-YYYYMMDDHHMMSS**_ is used.

The `--config` option is used to specify the [configuration file](#configuration-file) to be used.
This is required when the  `--generate` option is specified and is used to specify static information included
in the CSAF document. If this is not specified, a default filename of _**csaf.ini**_ in the current directory shall be assumed.
If the filename cannot be found, default values shall be used in the generation of the document.

Example usage:

```
csaf-tool --generate --product product.csv --vulnerabilities vulnerability.csv --id "Avendor-advisory-0004" --title "Technical summary" --header "Product backdoor identified" --output-file "test-csaf.json"
```

There is no output unless an error is detected due to missing parameters e.g.

```
[ERROR] Vulnerabilties filename not specified
```

#### Configuration File

A configuration file is used to specify a number of fixed parameters to be used in the generation of the CSAF document. The following is an example file.

```
# CSAF configuration file
[publisher]
# This is a comment which is ignored
category = vendor
name = Organisation
url = https://psirt.example.com
```

Comments are indicated by lines starting with '#'. All content is ignored.

The options are grouped into a single section **publisher**.

The following options are supported:

- *category* is used to specify the type of organisation publishing the CSAF document. Valid values for this are
"coordinator", "discoverer", "other", "translator", "user" or "vendor"

- *name* is used to specify the name of organisation publishing the CSAF document.

- *url* is used to specify a URL under the control of the organisation publishing the CSAF document.


### CSAF Analysis using command line

The `--input-file` option is used to specify the name of the CSAF document to be analysed by the tool.

Other parameters will be ignored.

Example usage:

```
csaf-tool --input-file test_pv.json
```

Sample output

```
                                                                                                                                             1 ⨯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ CSAF HEADER                                                                                                                                                                                │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Item                            ┃ Details                                ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ CSAF Version                    │ 2.0                                    │
│ Title                           │ Product backdoor identified            │
│ Category                        │ csaf_vex                               │
│ Date                            │ 2022-12-09T15-58-39Z                   │
│ Technical summary               │ Auto generated CSAF document           │
│ Publisher                       │ Organisation https://psirt.example.com │
│ Generator                       │ csaf-tool version 0.1.0                │
│ Id                              │ CSAF-Document-20221209155839           │
│ Revision 1 2022-12-09T15-58-39Z │ Initial version                        │
│ Status                          │ final                                  │
│ Version                         │ 1                                      │
└─────────────────────────────────┴────────────────────────────────────────┘
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ PRODUCT TREE                                                                                                                                                                               │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
┏━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┓
┃ Family ┃ Product   ┃ Vendor   ┃ Release ┃
┡━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━┩
│        │ product_1 │ AVendor  │ 1.1     │
│        │ product_1 │ AVendor  │ 1.2     │
│        │ product_1 │ AVendor  │ 2.0     │
│        │ product_2 │ AVendor1 │ 1       │
│        │ product_3 │ AVendor  │ 2022H2  │
└────────┴───────────┴──────────┴─────────┘
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ VULNERABILITIES                                                                                                                                                                            │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ VULNERABILITY CVE-2020-1234                                                                                                                                                                │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Item            ┃ Details                      ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ CVE ID          │ CVE-2020-1234                │
│ CVE description │ This is a simple description │
└─────────────────┴──────────────────────────────┘

KNOWN_AFFECTED
--------------

┏━━━━━━━━━━━┳━━━━━━━━━┓
┃ Product   ┃ Release ┃
┡━━━━━━━━━━━╇━━━━━━━━━┩
│ product_1 │ 1.1     │
└───────────┴─────────┘

Remediations
------------

VENDOR_FIX                               : Customers should upgrade to the latest version of the product
┏━━━━━━━━━━━┳━━━━━━━━━┓
┃ Product   ┃ Release ┃
┡━━━━━━━━━━━╇━━━━━━━━━┩
│ product_1 │ 1.1     │
└───────────┴─────────┘
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ VULNERABILITY CVE-2020-9876                                                                                                                                                                │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Item            ┃ Details                                  ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ CVE ID          │ CVE-2020-9876                            │
│ CVE description │ This is another vulnerabilty description │
└─────────────────┴──────────────────────────────────────────┘

KNOWN_AFFECTED
--------------

┏━━━━━━━━━━━┳━━━━━━━━━┓
┃ Product   ┃ Release ┃
┡━━━━━━━━━━━╇━━━━━━━━━┩
│ product_1 │ 1.1     │
└───────────┴─────────┘

Remediations
------------

NONE_AVAILABLE                           : Still under investigation
┏━━━━━━━━━━━┳━━━━━━━━━┓
┃ Product   ┃ Release ┃
┡━━━━━━━━━━━╇━━━━━━━━━┩
│ product_1 │ 1.1     │
└───────────┴─────────┘
```

An error message is reported if the specified file is not found.

```
[ERROR] CSAF filename not found
```

### CSAF Generation using the csaf library

The following example shows the generation of a CSAF document.

```
from csaf.generator import CSAFGenerator

csaf_gen = CSAFGenerator("csaf.ini")
# Define header information
csaf_gen.set_title("Test CSAF document")
csaf_gen.set_header_title("Example VEX Document Use Case 1 - Affected")

# Define product tree
csaf_gen.add_product(product_name = "product1", vendor = "Avendor", release = 1 )
csaf_gen.add_product(product_name = "product1", vendor = "Avendor", release = 2 )
csaf_gen.add_product(product_name = "product1", vendor = "Avendor", release = 3 )
csaf_gen.add_product(product_name = "product2", vendor = "Avendor1", release = 1.0 )
csaf_gen.add_product(product_name = "product2", vendor = "Avendor1", release = 1.1 )
csaf_gen.add_product(product_name = "product3", vendor = "Avendor", release = 1 )
csaf_gen.add_product(product_name = "product3", vendor = "Avendor", release = 2 )
csaf_gen.add_product(product_name = "product3", vendor = "Avendor", release = 3 )

# Add vulnerabilities 
csaf_gen.add_vulnerability(product_name = "product2", release = 1.1, id="CVE-2020-1234", description="A simple example", status="vendor_fix", comment="Upgrade product to latest version.")
csaf_gen.add_vulnerability(product_name = "product2", release = 1.1, id="CVE-2020-9876", description="Another simple example", status="none_available", comment="Still under review.")

# Generate the CSAF
csaf_gen.generate_csaf()
# And publish to file
csaf_gen.publish_csaf("test_csaf.json")
```

### CSAF Analysis using the csaf library

The following code sample can be used to analyse a CSAF file. It can be used to confirm that the CSAF file conforms with the CSAF specification

```
from csaf.analyser import CSAFAnalyser

try:
    csaf_filename = "test_csaf.json"
    csaf = CSAFAnalyser(csaf_filename)
    print (f"Is {csaf_filename} a valid CSAF document : {csaf.validate()}")
    csaf.analyse()
except FileNotFoundError:
    print ("[ERROR] CSAF filename not found")
```

## Licence

Licenced under the MIT Licence.

## Feedback and Contributions

Bugs and feature requests can be made via GitHub Issues.