CVE#

Common Vulnerabilities and Exposures Identifier (CVE ID) is a unique, alphanumeric identifier assigned by the CVE Program. Each identifier references a specific vulnerability. A CVE ID enables automation and multiple parties to discuss, share, and correlate information about a specific vulnerability, knowing they are referring to the same thing

source: www.cve.org

You can see this notebook directly via:

Generation time#

from datetime import datetime, timezone, timedelta

timezone_offset = 0.0
tzinfo = timezone(timedelta(hours=timezone_offset))
generation_time = datetime.now(tzinfo).strftime('%Y-%m-%d %H:%M:%S %z')
print(generation_time)
2023-04-08 09:29:26 +0000

Creative Commons#

This notebook and generated diagrams are released with Creative Commons liecense (CC BY 4.0).

CC BY 4.0

import requests
import urllib3

urllib3.disable_warnings()

urls = ['https://mirrors.creativecommons.org/presskit/icons/cc.xlarge.png',
       'https://mirrors.creativecommons.org/presskit/icons/by.xlarge.png']
for url in urls:
    file_name = url.split("/")[-1:][0]
    print(file_name)

    file = requests.get(url, verify=False)
    open(file_name, 'wb').write(file.content)
cc.xlarge.png
by.xlarge.png

CVE data downloading#

All CVE IDs are taken from cve.mitre.org/data/downloads/index.html

url = 'https://cve.mitre.org/data/downloads/allitems.xml.Z'
file_name = url.split("/")[-1:][0]
print(file_name)
allitems.xml.Z
import requests
import urllib3

urllib3.disable_warnings()

file = requests.get(url, verify=False)
open(file_name, 'wb').write(file.content)
60999413
import unlzw3
from pathlib import Path

uncompressed_data = unlzw3.unlzw(Path(file_name))
with open(file_name[:-2], 'wb') as file:
    file.write(uncompressed_data)
import glob

file_name = glob.glob('*.xml')[-1]
print(file_name)
allitems.xml

CVE data parsing#

import pandas as pd 
import xml.etree.ElementTree as et 

tree = et.parse(file_name)
root = tree.getroot()
df_cols = ["number", "year"]
rows = []

for item in root:
    item_name = item.attrib.get("name")
    item_year = item_name[4:8]
    rows.append({"number": item_name, "year": item_year})

df = pd.DataFrame(rows, columns = df_cols)

print(df)
                number  year
0        CVE-1999-0001  1999
1        CVE-1999-0002  1999
2        CVE-1999-0003  1999
3        CVE-1999-0004  1999
4        CVE-1999-0005  1999
...                ...   ...
269592  CVE-2023-30425  2023
269593  CVE-2023-30426  2023
269594  CVE-2023-30427  2023
269595  CVE-2023-30428  2023
269596  CVE-2023-30429  2023

[269597 rows x 2 columns]
df = df.groupby(['year'], as_index=False)[['number']].count()
df.reset_index(drop=True, inplace=True)
df.index += 1

df.style.bar(subset=['number'], color='#FF6200')
  year number
1 1999 1579
2 2000 1243
3 2001 1573
4 2002 2436
5 2003 1603
6 2004 2779
7 2005 4900
8 2006 7256
9 2007 6766
10 2008 7325
11 2009 5163
12 2010 5349
13 2011 5339
14 2012 6733
15 2013 7520
16 2014 10549
17 2015 9672
18 2016 11357
19 2017 19567
20 2018 21914
21 2019 21541
22 2020 31262
23 2021 30604
24 2022 33276
25 2023 12291

CVE data saving#

CSV file is available in GitHub repository, see:

csv_filename = 'cve-number-of-entries.csv'

df.to_csv(csv_filename, index=False)

CVE data ploting#

PNG files are available in GitHub repository with two background versions, see:

import pandas as pd
import matplotlib.pyplot as plt
import datetime

df = pd.read_csv(csv_filename)

df.plot(x='year', 
        xlabel='Year',
        y='number', 
        ylabel='Number of CVE',
        kind='bar', 
        title='Number of CVE per year')
plt.tight_layout()
plt.legend(['CVE'])
plt.figtext(0.15, 0.02, f"Generated on {generation_time} thanks to limberduck.org based on source: cve.mitre.org", ha="left", fontsize=7)
fig = plt.gcf()
fig.set_size_inches(10,6)
fig.patch.set_facecolor('white')
plt.grid(True)

img_cc = plt.imread('cc.xlarge.png')
newax_cc = fig.add_axes([0.88, 0.0, 0.05, 0.05], anchor='NE', zorder=-1)
newax_cc.imshow(img_cc)
newax_cc.axis('off')
img_by = plt.imread('by.xlarge.png')
newax_by = fig.add_axes([0.92, 0.0, 0.05, 0.05], anchor='NE', zorder=-1)
newax_by.imshow(img_by)
newax_by.axis('off')

plt.savefig('cve-number-of-entries-bg-white.png', dpi = 300, facecolor = 'white')
plt.savefig('cve-number-of-entries-bg-transparent.png', dpi = 300, transparent = True)
../../_images/b72716354a3479820ce403445ddc6429d22f482cd9b8013da50f9941fdf88a89.png