-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmain.py
115 lines (101 loc) · 3.92 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import requests
import html
import re
import time
import random
from datetime import datetime
from peewee import *
# Constants
DB_FILE = "db/cve.sqlite"
README_FILE = "docs/README.md"
API_URL = "https://api.github.com/search/repositories?q=CVE-{}&sort=updated&page=3&per_page=500"
# Database setup
db = SqliteDatabase(DB_FILE)
class CVE_DB(Model):
id = IntegerField()
full_name = CharField(max_length=1024)
description = CharField(max_length=200)
url = CharField(max_length=1024)
created_at = CharField(max_length=128)
cve = CharField(max_length=64)
class Meta:
database = db
# Initialize database
def initialize_db():
db.connect()
db.create_tables([CVE_DB])
# Initialize README file
def initialize_readme():
with open(README_FILE, 'w') as f:
f.write("# Github CVE Monitor\n\n> Automatic monitor github cve using Github Actions\n\n")
f.write("Last generated: {}\n\n".format(datetime.now()))
f.write("| CVE | Name | Description | Date |\n|---|---|---|---|\n")
# Write to README file
def write_to_readme(new_contents):
with open(README_FILE, 'a') as f:
f.write(new_contents)
# Get CVE information from GitHub API
def get_cve_info(year):
try:
req = requests.get(API_URL.format(year)).json()
return req.get("items", [])
except Exception as e:
print("An error occurred in the network request:", e)
return []
# Match CVEs and insert into database
def match_and_insert_cves(items):
regex = r"[Cc][Vv][Ee][-_]\d{4}[-_]\d{4,7}"
cve_list = []
for item in items:
id = item["id"]
if CVE_DB.select().where(CVE_DB.id == id).count() != 0:
continue
full_name = html.escape(item["full_name"])
description = item.get("description") # Get description from item
if description:
description = html.escape(description.strip()) # Escape description if it exists
else:
description = "no description" # Set default description if it's None
url = item["html_url"]
cve = re.search(regex, url + description).group() if re.search(regex, url + description) else "CVE Not Found"
created_at = item["created_at"]
cve_list.append({
"id": id,
"full_name": full_name,
"description": description,
"url": url,
"created_at": created_at,
"cve": cve.replace('_', '-')
})
CVE_DB.create(id=id, full_name=full_name, description=description, url=url, created_at=created_at, cve=cve.upper().replace('_', '-'))
return sorted(cve_list, key=lambda e: e["created_at"])
# Main function
def main():
initialize_db()
initialize_readme()
sorted_list = []
current_year = datetime.now().year
for year in range(current_year, 1999, -1):
cve_info = get_cve_info(year)
if not cve_info:
continue
print("Year {}: {} articles retrieved".format(year, len(cve_info)))
sorted_cves = match_and_insert_cves(cve_info)
if sorted_cves:
print("Year {}: {} articles updated".format(year, len(sorted_cves)))
sorted_list.extend(sorted_cves)
time.sleep(random.randint(3, 15))
# Write CVE information to README file
for cve_info in CVE_DB.select().order_by(CVE_DB.cve.desc()):
cve = cve_info.cve
full_name = cve_info.full_name
description = cve_info.description.replace('|', '-')
publish_date = cve_info.created_at
if cve.upper() == "CVE NOT FOUND":
newline = "| {} | [{}]({}) | {} | {} |\n".format(cve.upper(), full_name, cve_info.url, description, publish_date)
else:
newline = "| [{}]({}) | [{}]({}) | {} | {} |\n".format(cve.upper(), "https://www.cve.org/CVERecord?id=" + cve.upper(), full_name, cve_info.url, description, publish_date)
write_to_readme(newline)
# TODO: Add code for statistics
if __name__ == "__main__":
main()