Formatting the JS Report
But to make better sense of that json, we need to format it in a way that pulls out the critical info (for example, severity, description, and location) while leaving out noise (for example, dependency graphs). Let's use Python, which is great for string manipulation and general data munging, to write a script that formats that json into a plain text report. We'll call the script formatjs.py to associate it with our other tool. The first thing we need to do is pull in json from STDIN and encode it as a Python data structure:
#!/usr/bin/env python2.7
import sys, json
data = json.load(sys.stdin)
Our goal is to create a table to display the data from the report, covering the severity, summary, info, and file attributes for each vulnerability.
We'll be using a simple Python table library, tabulate (which you can install via pip install tabulate). As per the tabulate docs, you can create a table using a nested list, where the inner list contains the values of an individual table row. We're going to iterate over the different files analyzed, iterate over each vulnerability, and process their attributes into row lists that we'll collect in our rows nested list:
rows = []
for item in data:
for vulnerability in item['results'][0]['vulnerabilities']:
vulnerability['file'] = item.get('file', 'N/A')
row = format_bug(vulnerability)
rows.append(row)
That format_bug() function will just pull out the information we care about from the vulnerability dictionary and order the info properly in a list the function will return:
def format_bug(vulnerability):
row = [
vulnerability['severity'],
vulnerability.get('identifiers').get('summary', 'N/A') if vulnerability.get('identifiers', False) else 'N/A',
vulnerability['file'] + "\n" + vulnerability.get('info', ['N/A'])[0]
]
return row
Then we'll sort the vulnerabilities by severity so that all the different types (high, medium, low, and so on) are grouped together:
print(
"""
,--. ,---. ,-----.
| |' .-' | |) /_ ,--.,--. ,---. ,---.
,--. | |`. `-. | .-. \| || || .-. |( .-'
| '-' /.-' | | '--' /' '' '' '-' '.-' `)
`-----' `-----' `------' `----' .`- / `----'
`---'
""")
print tabulate(rows, headers=['Severity', 'Summary', 'Info & File'])
Here's what it looks like all together, for reference:
#!/usr/bin/env python2.7
import sys, json
from tabulate import tabulate
data = json.load(sys.stdin)
rows = []
def format_bug(vulnerability):
row = [
vulnerability['severity'],
vulnerability.get('identifiers').get('summary', 'N/A') if vulnerability.get('identifiers', False) else 'N/A',
vulnerability['file'] + "\n" + vulnerability.get('info', ['N/A'])[0]
]
return row
for item in data:
for vulnerability in item['results'][0]['vulnerabilities']:
vulnerability['file'] = item.get('file', 'N/A')
row = format_bug(vulnerability)
rows.append(row)
rows = sorted(rows, key=lambda x: x[0])
print(
"""
,--. ,---. ,-----.
| |' .-' | |) /_ ,--.,--. ,---. ,---.
,--. | |`. `-. | .-. \| || || .-. |( .-'
| '-' /.-' | | '--' /' '' '' '-' '.-' `)
`-----' `-----' `------' `----' .`- / `----'
`---'
""")
print tabulate(rows, headers=['Severity', 'Summary', 'Info & File'])
And the following is what it looks like when it's run on the Terminal. I'm running the scanjs.sh script wrapper and then piping the data to formatjs.py. Here's the command:
./scanjs.sh ~/Code/Essences/demo test.json | python formatjs.py
And here's the output: